Python 如何在列表列表中使用reduce
以下内容有什么问题Python 如何在列表列表中使用reduce,python,list,python-2.7,Python,List,Python 2.7,以下内容有什么问题 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 bu
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'
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
lss=reduce(list.extend、[[1]、[2]]、[]
TypeError:描述符“extend”需要一个“list”对象,但收到了一个“NoneType”
我不确定NoneType
是从哪里来的。试试这个:
lss = reduce(lambda acc, ele : acc + ele, [[1],[2]], [])
lss
> [1, 2]
问题是返回的是
None
(这就是NoneType
的来源),这与您想要执行的操作无关-传递给的函数必须返回一个值:到目前为止的累积结果。我认为值得注意的是:
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上(因为,为什么不)
结论:
sum
函数比reduce更快正如奥斯卡·洛佩斯所指出的,
list.extend
返回None
,因此不能与reduce
一起使用。除了建议使用lambda
功能外,您还可以使用list.\uu添加\uuuu
和reduce
:
>>> reduce(list.__add__, [[1],[2]], [])
[1, 2]
您可能想使用
生成一个迭代器,从第一个iterable返回元素,直到
它已耗尽,然后继续下一个iterable,直到所有
人们都筋疲力尽了。用于将连续序列作为一个整体处理
单一序列。相当于:
我意识到我能做到。我仍然想知道使用list.extend方法有什么问题。看来它应该有用您的编辑回答了这个问题。@cammil正如我上面提到的:
extend()
将始终返回None
;要使reduce()
工作,执行的函数必须返回一个值:到目前为止的累积结果。如果有人想知道为什么list.extend()
返回None
:这是因为在Python中,改变数据结构的函数总是返回None
,因为Python遵循命令/查询分离。你想要的结果是什么?/你想扩展什么列表?如果你设置x=x*100,你就可以开始看到算法之间的实际速度差异。不幸的是,这个基准中缺少的是:列表(itertools.chain.from_iterable(x))
和[b代表x中的a代表a中的b]
。第一种可能是最快的选择。@SvenMarnach,他们补充道。然而,我的结果显示它们都比一些现有的选项慢。在我测试的两台机器上,list(itertools.chain.from_iterable(x))
始终比list(itertools.chain(*x))
快,而且对于没有示例列表人为高缓存局部性的较大列表来说,这是一个很大的差距(这是由于*100
重复使用了数百次相同的列表造成的)。它确实比y=[];map(y.extend,x)
慢。有趣的帖子!@SvenMarnach,我继续并重新运行了所有测试,我的结果现在符合您的经验。
>>> reduce(list.__add__, [[1],[2]], [])
[1, 2]
def chain(*iterables):
# chain('ABC', 'DEF') --> A B C D E F
for it in iterables:
for element in it:
yield element