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

我正在探索 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:香草嵌套 for 循环

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

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


叮当猫咪
浏览 173回答 1
1回答

波斯汪

你在比较不同的东西:[(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]第一个完全跳过第二个循环 if x%2 != 0,第二个循环遍历所有1000 ** 2 == 1,000,000组合。案例 2 到 4 与这里的第二个理解属于同一类,因此它们本质上是较慢的。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python