Jea*_*bre 13 python performance list-comprehension
我在Python中没有[]读过关于列表理解的内容,所以现在我知道了
''.join([str(x) for x in mylist])
Run Code Online (Sandbox Code Playgroud)
比...更快
''.join(str(x) for x in mylist)
Run Code Online (Sandbox Code Playgroud)
因为"列表推导得到高度优化"
所以我认为优化依赖于for
表达式的解析,查看mylist
,计算其长度,并使用它来预先分配精确的数组大小,这节省了大量的重新分配.
使用时''.join(str(x) for x in mylist)
,join
盲目地接收发电机,并且必须在不事先知道尺寸的情况下建立其列表.
但现在考虑一下:
mylist = [1,2,5,6,3,4,5]
''.join([str(x) for x in mylist if x < 4])
Run Code Online (Sandbox Code Playgroud)
python如何决定列表理解的大小?它是根据大小计算的mylist
,并且在迭代完成时缩小(如果列表很大并且条件过滤掉99%的元素,这可能非常糟糕),或者它是否会恢复为"不知道提前大小"案例?
编辑:我做了一些小基准测试,似乎确认有一个优化:
没有条件:
import timeit
print(timeit.timeit("''.join([str(x) for x in [1,5,6,3,5,23,334,23234]])"))
print(timeit.timeit("''.join(str(x) for x in [1,5,6,3,5,23,334,23234])"))
Run Code Online (Sandbox Code Playgroud)
收益率(如预期):
3.11010817019474
3.3457350077491026
Run Code Online (Sandbox Code Playgroud)
有条件:
print(timeit.timeit("''.join([str(x) for x in [1,5,6,3,5,23,334,23234] if x < 50])"))
print(timeit.timeit("''.join(str(x) for x in [1,5,6,3,5,23,334,23234] if x < 50)"))
Run Code Online (Sandbox Code Playgroud)
收益率:
2.7942209702566965
3.0316467566203276
Run Code Online (Sandbox Code Playgroud)
所以条件listcomp仍然更快.
use*_*ica 12
列表推导不会预先确定列表的大小,即使它们完全可以.您假设存在未实际完成的优化.
列表理解更快,因为所有迭代器机制以及进入和退出genexp堆栈帧的工作都有成本.列表理解不需要支付该费用.