在 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) 等。
一个或另一个的任何优点?想法?
原文由 cschol 发布,翻译遵循 CC BY-SA 4.0 许可协议
两者只有细微差别。您可以使用
dis
模块自己检查这类事情。编辑: 我的第一个版本在交互式提示中反编译了在模块范围内创建的生成器表达式。这与函数内部使用的 OP 版本略有不同。我修改了它以匹配问题中的实际情况。
正如您在下面看到的,“yield”生成器(第一种情况)在设置中有三个额外的指令,但是从第一个
FOR_ITER
它们只有一个方面不同:“yield”方法使用了一个LOAD_FAST
代替循环内的LOAD_DEREF
。LOAD_DEREF
比LOAD_FAST
“相当慢” ,因此对于足够大的值x
(the外循环),因为y
的值在每次传递时加载速度稍快。对于x
的较小值,由于设置代码的额外开销,它会稍微慢一些。可能还值得指出的是,生成器表达式通常会在代码中内联使用,而不是像那样用函数包装它。这将消除一些设置开销,并使生成器表达式对于较小的循环值稍微更快,即使
LOAD_FAST
给“yield”版本带来了优势。在这两种情况下,性能差异都不足以证明在两者之间做出决定是合理的。可读性更重要,所以使用最适合手头情况的可读性。