itertools.product与列表理解之间的性能差异

问题描述 投票:0回答:1

我正在研究Python的itertools模块,并遇到了itertools.product函数,该函数返回的内容与((x,y) for x in A for y in B)相同。我发现这是减少列表理解可能不足的复杂for-loops中嵌套的一种真正好方法。但是,在继续之前,我想检查一下其他方法的效果。这是我进行的一些测试。使用Jupyter Notebook的内置%%timeit来衡量性能。

案例1:基本列表理解

%%timeit -n 50 -r 5

[(x,y) for x in range(1000) if x%2==0 for y in range(1000) if y%2==1]
>>> 35.8 ms ± 1.3 ms per loop (mean ± std. dev. of 5 runs, 50 loops each)

案例2:列表理解中的itertools.product

已删除itertools导入以避免在此处显示导入时间。

%%timeit -n 50 -r 5

[(x,y) for (x,y) in itertools.product(range(1000), range(1000)) if x%2==0 and y%2==1]
>>> 62.1 ms ± 1.16 ms per loop (mean ± std. dev. of 5 runs, 50 loops each)

情况3:香草嵌套为循环

%%timeit -n 50 -r 5

lst = []
for x in range(1000):
    for y in range(1000):
       if x%2 == 0 and y%2 == 1:
           lst.append((x,y))
>>> 72 ms ± 769 µs per loop (mean ± std. dev. of 5 runs, 50 loops each)

情况4:使用itertools.product的for循环

%%timeit -n 50 -r 5

lst = []
for x, y in itertools.product(range(1000),range(1000)):
    if x%2==0 and y%2==1:
        lst.append((x,y))
>>> 74.5 ms ± 2.13 ms per loop (mean ± std. dev. of 5 runs, 50 loops each)

但是,我想文档的this部分声称比普通的for循环具有更好的性能。另外,case-2是否应该比case-1快?在case-3case-4中,itertools.product的性能差异随着可迭代项的大小增加而变差。这里发生了什么?另外,请添加一些示例,其中itertools.product可能比listcomp或嵌套for循环更好。

python python-3.x loops functional-programming itertools
1个回答
2
投票

您正在比较不同的事物:

[(x,y) for x in range(1000) if x%2==0 for y in range(1000) if y%2==1]

...与]不同

[(x,y) for x in range(1000) for y in range(1000) if x%2==0 and y%2==1]

如果x%2 != 0,第一个循环完全跳过第二个循环,第二个循环遍历所有1000 ** 2 == 1,000,000组合。案例2至4与此处的第二个理解属于同一类别,因此它们本质上较慢。

© www.soinside.com 2019 - 2024. All rights reserved.