我读了有关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%的元素,则可能非常糟糕),还是会回到“事先不知道大小”的情况?编辑:我进行了一些小型基准测试,似乎证实了存在优化:
没有条件:
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
所以条件列表推导仍然更快。
for x in xx for y in yy
的行为在使用链接问题和for x in y if x<123
的行为应该是相似的,因为在这两种情况下,Python在表达式被评估之前不知道结果列表的大小。 (这只是逻辑假设,不确定是否正确) - Moinuddin Quadrijoin
如果还不是列表,它会创建一个列表来确定大小。问题是关于列表推导式在有条件语句时如何计算大小的。现在我开始相信最坏情况下会分配空间大小,并且在后面缩小列表大小。 - Jean-François FabrePyBytes_GET_SIZE
,然后您可能会找到答案。 - Mazdak