在Python中,通过生成器表达式创建生成器对象与使用yield语句创建生成器对象有什么区别吗?
使用屈服:
def Generator(x, y):
for i in xrange(x):
for j in xrange(y):
yield(i, j)
使用生成器表达式:
def Generator(x, y):
return ((i, j) for i in xrange(x) for j in xrange(y))
两个函数都返回生成元组的生成器对象,例如(0,0),(0,1)等
有什么好处吗?思想?
谢谢大家!在这些答案中有很多很好的信息和进一步的参考!
在这个例子中,不是真的。但是
yield
可以用于更复杂的构造-for example它还可以接受来自调用方的值,并因此修改流。阅读PEP 342了解更多细节(这是一种值得了解的有趣技术)。不管怎样,最好的建议是根据自己的需要使用更清晰的内容。
p.S.这里有一个来自Dave Beazley的简单协同程序示例:
对于可以放入生成器表达式中的简单循环类型没有区别。然而,yield可以用来创建执行更复杂处理的生成器。下面是生成斐波那契序列的一个简单示例:
两者只有细微的差别。您可以使用
dis
模块自己检查这类事情。编辑:我的第一个版本在交互提示中反编译了在模块范围内创建的生成器表达式。这与OP的版本略有不同,它在函数中使用。我修改了这个以符合问题中的实际情况。
如下所示,“yield”生成器(第一种情况)在设置中有三个额外的指令,但从第一个
FOR_ITER
开始,它们只在一个方面有所不同:“yield”方法使用LOAD_FAST
代替循环中的LOAD_DEREF
。LOAD_DEREF
比LOAD_FAST
快"rather slower",因此它使“yield”版本比生成器表达式稍快,以获得足够大的x
(外循环)值,因为y
的值在每次传递时加载得稍快。对于较小的x
值,由于设置代码的额外开销,速度会稍微慢一些。可能还需要指出的是,生成器表达式通常在代码中内联使用,而不是像那样用函数包装它。即使
LOAD_FAST
为“yield”版本提供了其他优势,这也会减少一些设置开销,并使生成器表达式对于较小的循环值保持稍快的速度。在这两种情况下,性能差异都不足以证明在两者之间做出决定是合理的。可读性更为重要,所以在手边的情况下,使用感觉最可读的。
相关问题 更多 >
编程相关推荐