这是一个生成器表达式。要让它在独立的情况下工作,请使用大括号:
y = (x for x in range(10))
并且 y 成为一个生成器。您可以迭代生成器,因此它可以在预期可迭代的地方工作,例如sum
函数。
使用示例和陷阱:
>>> y = (x for x in range(10))
>>> y
<generator object <genexpr> at 0x0000000001E15A20>
>>> sum(y)
45
随身携带发电机时要小心,您只能通过它们一次。所以在上述之后,如果你再次尝试使用sum
,就会出现这种情况:
>>> sum(y)
0
因此,如果您传递的生成器实际上是一个列表或集合或类似的东西,您必须小心。如果函数或类存储参数并尝试多次迭代它,您将遇到问题。例如考虑这个:
def foo(numbers):
s = sum(numbers)
p = reduce(lambda x,y: x*y, numbers, 1)
print "The sum is:", s, "and the product:", p
如果你给它一个生成器,它会失败:
>>> foo(x for x in range(1, 10))
The sum is: 45 and the product: 1
您可以轻松地从生成器生成的值中获取列表:
>>> y = (x for x in range(10))
>>> list(y)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
您可以使用它来修复前面的示例:
>>> foo(list(x for x in range(1, 10)))
The sum is: 45 and the product: 362880
但是请记住,如果您从生成器构建列表,则需要存储每个值。在您有很多项目的情况下,这可能会使用更多内存。
为什么在您的情况下使用生成器?
低得多的内存消耗是sum(generator expression)
优于的原因sum(list)
:生成器版本只需存储单个值,而列表变体必须存储 N 个值。因此,您应该始终使用不会产生副作用的生成器。