gpt4 book ai didi

python - 嵌套的 python 生成器有多快?

转载 作者:太空宇宙 更新时间:2023-11-04 08:18:21 25 4
gpt4 key购买 nike

好吧,所以我可能不应该担心这个,但我有一些代码是为了通过一组过滤器和 map 传递一个(可能很长,可能很短)可能性列表,并且其他事情,我想知道我的实现是否会表现良好。

作为我想做的事情的一个例子,考虑这个操作链:

  • 获取从 1 到 100 的所有数字
  • 只保留偶数
  • 将每个数字平方
  • 用上面列表中的 i 和 [1, 2, 3, 4,5] 中的 j 生成所有对 [i, j]
  • 只保留 i + j > 40 的对

现在,在做了所有这些废话之后,我想通过这组对 [i, j] 来寻找满足特定条件的对。通常,解决方案是第一个条目之一,在这种情况下,我什至不看任何其他条目。然而,有时我必须使用整个列表,但找不到答案而不得不抛出错误。

我想将我的“操作链”实现为一系列生成器,即每个操作迭代前一个生成器生成的项目,并逐项“产生”自己的输出(SICP 流)。这样,如果我从不查看输出的最后 300 个条目,它们甚至不会得到处理。我知道 itertools 提供了 imap 和 ifilter 之类的东西来执行我想要执行的许多类型的操作。

我的问题是:在我必须遍历所有可能性的情况下,一系列嵌套生成器是否会对性能产生重大影响?

最佳答案

我尝试了两种实现方式,一种使用生成器,一种不使用生成器。我在 2.7 中对其进行了测试,因此 range 返回一个列表而不是迭代器。

这里是实现

使用生成器

def foo1():
data = ((a,b) for a in (i*i for i in xrange(1,101) if i%2) for b in [1,2,3,4,5] if a+b > 40)
return list(data)

没有发电机

def foo2():
result=[]
for i in range(1,101):
if i%2:
i=i*i
for j in [1,2,3,4,5]:
if i+j > 40:
result+=[(i,j)]
return result

混合两者以免附加列表

def foo3():
data=[(a,b) for a in (i*i for i in range(1,101)) for b in [1,2,3,4,5] if a+b > 40]
return data

创建临时列表

def foo4():
data=[(a,b) for a in [i*i for i in range(1,101)] for b in [1,2,3,4,5] if a+b > 40]
return data

这是我的结果

>>> t1=timeit.Timer("foo1()","from __main__ import foo1")
>>> t2=timeit.Timer("foo2()","from __main__ import foo2")
>>> t3=timeit.Timer("foo3()","from __main__ import foo3")
>>> t4=timeit.Timer("foo4()","from __main__ import foo4")

>>> print "%.2f usec/pass" % (1000000 * t1.timeit(number=10000)/10000)
100.95 usec/pass
>>> print "%.2f usec/pass" % (1000000 * t2.timeit(number=10000)/10000)
158.90 usec/pass
>>> print "%.2f usec/pass" % (1000000 * t3.timeit(number=10000)/10000)
130.02 usec/pass
>>> print "%.2f usec/pass" % (1000000 * t4.timeit(number=10000)/10000)
133.68 usec/pass
>>>

结论:

生成器表达式非常强大,您可以对其进行更大程度的优化。正如您在示例 foo2 中看到的那样,这是最慢的,它很难附加单个列表,从而降低了性能。 foo3foo4 的时间几乎相同,所以创建临时列表似乎不是瓶颈,因为它在整个迭代中只创建了一次。如果没有生成器,您很快就会遇到一些性能问题,例如附加列表或创建临时列表。因此惰性求值应运而生,以克服这些性能瓶颈。

关于python - 嵌套的 python 生成器有多快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10143637/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com