python如何优化条件列表推导

时间:2017-01-07 09:04:20

标签: python performance list-comprehension

我读到List comprehension without [ ] in Python所以现在我知道了

''.join([str(x) for x in mylist])

''.join(str(x) for x in mylist)

因为"列表推导得到了高度优化"

所以我认为优化依赖于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])

python如何决定列表理解的大小?它是根据mylist的大小计算的,并且在迭代完成时缩小(如果列表很大并且条件过滤掉99%的元素,这可能非常糟糕),或者它是否会恢复为& #34;事先不知道大小&#34;情况?

编辑:我已经完成了一些小的基准测试,似乎确认有一个优化:

没有条件:

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])"))

收益率(如预期):

3.11010817019474
3.3457350077491026

条件:

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)"))

的产率:

2.7942209702566965
3.0316467566203276

所以条件listcomp仍然更快。

1 个答案:

答案 0 :(得分:12)

列表理解预先确定列表的大小,即使它们完全可以。您假设存在未实际完成的优化。

列表理解更快,因为所有迭代器机制以及进入和退出genexp堆栈帧的工作都有成本。列表理解不需要支付这笔费用。