我没有Python经验,我经常编写(简化)代码如下:
accumulationList = []
for x in originalList:
y = doSomething(x)
accumulationList.append(y)
return accumulationList
然后在我的测试通过后,我重构
return [doSomething(x) for x in originalList]
但是假设结果有点不同,我的循环看起来像这样:
accumulationList = []
for x in originalList:
y = doSomething(x)
accumulationList.extend(y)
return accumulationList
doSomething
列表返回列表。什么是最恐怖的方式来实现这一目标?显然,之前的列表理解会给出一个列表列表。
答案 0 :(得分:9)
列表理解更简单,更清晰:
[y for x in originalList for y in doSomething(x)]
答案 1 :(得分:4)
你的意思是这样吗?
accumulationList = []
for x in originalList:
accumulationList.extend(doSomething(x))
return accumulationList
或更短的代码(但不是最佳的):
return sum((doSomething(x) for x in originalList), [])
或相同:
return sum(map(doSomething, originalList), [])
感谢@eyquem的提示(如果使用Python 2.x):
import itertools as it
return sum(it.imap(doSomething, originalList), [])
答案 2 :(得分:2)
Python的就地添加运算符(+=
,在iadd
模块中可用operator
)相当于列表的.extend
。将其与reduce
配对即可获得所需内容。
import operator
reduce(operator.iadd, (doSomething(x) for x in originalList)
, accumulation_list)
答案 3 :(得分:2)
我认为涉及add或iadd的答案在二次时间内运行,这可能并不好。我试试:
from itertools import chain
accumulation_list = list(chain.from_iterable(doSomething(x) for x in originalList))
答案 4 :(得分:0)
我认为这种情况没有特殊的语法。但你可以缩短for循环:
accumulationList += doSomething(x)
如果你坚持,你可以使用函数式编程来压缩列表:
result = reduce(lambda a,b: a+b, [[i,i*2] for i in range(3)])
但我不会称之为pythonic,我认为它比for循环更难阅读。
答案 5 :(得分:0)
Functionally,您可以将itertools.chain
与map
一起使用。对于输入列表L
:
res = list(chain.from_iterable(map(doSomething, L)))
如果需要迭代器,只需删除list
调用即可。这是一个演示:
def doSomething(value):
return [value * i for i in range(1, 4)]
def original(originalList):
accumulationList = []
for x in originalList:
y = doSomething(x)
accumulationList.extend(y)
return accumulationList
def new(L):
return list(chain.from_iterable(map(doSomething, L)))
x = [1, 2, 3]
assert original(x) == new(x)
print(new(x))
[1, 2, 3, 2, 4, 6, 3, 6, 9]