这是莫名其妙的后续这个问题
首先,你会注意到你不能sum在一个字符串列表上执行连接它们,python告诉你使用它str.join,这是一个很好的建议,因为无论你如何使用+字符串,性能都很糟糕.
"不能使用sum"限制不适用于list,但是,这itertools.chain.from_iterable是执行此类列表展平的首选方法.
但是sum(x,[])什么时候x列表清单肯定是坏的.
但是它应该保持这种状态吗?
我比较了3种方法
import time
import itertools
a = [list(range(1,1000)) for _ in range(1000)]
start=time.time()
sum(a,[])
print(time.time()-start)
start=time.time()
list(itertools.chain.from_iterable(a))
print(time.time()-start)
start=time.time()
z=[]
for s in a:
z += s
print(time.time()-start)
Run Code Online (Sandbox Code Playgroud)
结果:
sum()在列表中:10.46647310256958.好的,我们知道.itertools.chain:0.07705187797546387itertools.chain您看到的更快)所以sum落后了,因为它result = result + b代替了result += b
所以现在我的问题是:
为什么不能sum在可用时使用这种累积方法?
(这对于现有的应用程序来说是透明的,并且可以使用sum内置的内容来有效地压缩列表)
我在这里回答了几个问题,用它来"压扁"列表列表:
>>> l = [[1,2,3],[4,5,6],[7,8,9]]
>>> sum(l,[])
Run Code Online (Sandbox Code Playgroud)
它工作正常,产量:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
Run Code Online (Sandbox Code Playgroud)
虽然我被告知sum操作员做a = a + b的不是那么高效itertools.chain
我计划的问题是"为什么它可以在字符串上阻止字符串",但我在我的机器上做了一个快速的基准测试比较sum和itertools.chain.from_iterable相同的数据:
import itertools,timeit
print(timeit.timeit("sum(l,[])",setup='l = [[1,2,3],[4,5,6],[7,8,9]]'))
print(timeit.timeit("list(itertools.chain.from_iterable(l))",setup='l = [[1,2,3],[4,5,6],[7,8,9]]'))
Run Code Online (Sandbox Code Playgroud)
我这样做了几次,我总是得到与下面相同的数字:
0.7155522836070246
0.9883352857722025
Run Code Online (Sandbox Code Playgroud)
令我惊讶的是,chain- sum在我的答案的几条评论中,每个人推荐列表 - 速度要慢得多.
在循环中迭代时仍然很有趣,for因为它实际上并不创建列表,但是在创建列表时,sum获胜.
那么当预期结果是什么时我们应该放弃itertools.chain并使用?sumlist
编辑:感谢一些评论,我通过增加列表数量进行了另一项测试
s = 'l = [[4,5,6] for _ in range(20)]'
print(timeit.timeit("sum(l,[])",setup=s))
print(timeit.timeit("list(itertools.chain.from_iterable(l))",setup=s))
Run Code Online (Sandbox Code Playgroud)
现在我反其道而行之:
6.479897810702537
3.793455760814343
Run Code Online (Sandbox Code Playgroud)