以下是什么问题?:
lss = reduce(list.extend, [[1],[2]], [])
导致:
Traceback (most recent call last):
File "<pyshell#230>", line 1, in <module>
lss = reduce(list.extend, [[1],[2]], [])
TypeError: descriptor 'extend' requires a 'list' object but received a 'NoneType'
我不确定NoneType
的来源。
答案 0 :(得分:13)
请改为尝试:
lss = reduce(lambda acc, ele : acc + ele, [[1],[2]], [])
lss
> [1, 2]
问题是extend()
返回None
(这是NoneType
来自的地方),这对你想做的事情不起作用 - 传递给{的函数{3}} 必须返回一个值:到目前为止的累计结果。
答案 1 :(得分:5)
我认为值得注意的是:
sum([[1],[2]], [])
也会有效,而且我非常肯定会比传递lambda更快。
我很好奇不同方法的速度,所以我做了一些测试:
reduce(lambda a,b:a+b, x, []) 3644.38161492
reduce(list.__add__, x, []) 3609.44079709
sum(x,[]) 3526.84987307
y = [];for z in x: y.extend(z) 143.370306969
y = [];map(y.extend,x) 71.7020270824
y = [None]*400;del y[:];map(y.extend,x) 66.2245891094
list(itertools.chain(*x)) 102.285979986
list(itertools.chain.from_iterable(x)) 96.6231369972
[a for b in x for a in b] 203.764872074
在PyPy上(因为,为什么不呢)
reduce(lambda a,b:a+b, x, []) 4797.5895648
reduce(list.__add__, x, []) 4794.01214004
sum(x,[]) 4748.02929902
y = [];for z in x: y.extend(z) 56.9253079891
y = [];map(y.extend,x) 73.8642170429
y = [None]*400;del y[:];map(y.extend,x) 152.157783031
list(itertools.chain(*x)) 633.854824066
list(itertools.chain.from_iterable(x)) 629.917827129
[a for b in x for a in b] 89.6922459602
x = [[1,2,3,4],[2,3,4,5],[3,4,5,6],[4,5,6,7],[5,6,7,8],[6,7,8,9],[7,8,9,10],[8,9,10,11]]*100
结论:
sum
功能比缩小答案 2 :(得分:1)
如ÓscarLópez所述,list.extend
会返回None
,因此无法与reduce
一起使用。作为lambda
功能的建议使用的替代方案,您也可以将list.__add__
与reduce
一起使用:
>>> reduce(list.__add__, [[1],[2]], [])
[1, 2]
答案 3 :(得分:1)
您可能想要使用itertools.chain
创建一个迭代器,返回第一个iterable中的元素,直到 它耗尽,然后进入下一个迭代,直到所有的 迭代用尽了。用于处理连续序列 单一序列。相当于:
def chain(*iterables):
# chain('ABC', 'DEF') --> A B C D E F
for it in iterables:
for element in it:
yield element