我探索了Python的itertools模块,并看到了返回与((x,y) for x in A for y in B)相同的itertools.product函数。我发现这是在复杂的for-loops中减少嵌套的一种非常巧妙的方法,在这种情况下,列表理解可能不够。但是,在继续之前,我想检查它如何使用替代方法执行。这是我做过的一些测试。使用木星笔记本的内置%%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)但是,我认为文档中的这部分比普通的for循环具有更好的性能。另外,case-2不应该比case-1更快吗?在case-3和case-4中,随着可迭代性的增加,itertools.product的性能差异越来越大。这里发生什么事情?另外,请添加一些示例,其中itertools.product可能是比listcomp或嵌套for循环更好的选择。
发布于 2020-04-26 08:59:55
你在比较不同的东西:
[(x,y) for x in range(1000) if x%2==0 for y in range(1000) if y%2==1]...is与
[(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与这里的第二个理解属于同一类别,因此它们本身就比较慢。
https://stackoverflow.com/questions/61438122
复制相似问题