我提出这个代码拉入请求:
my_sum = sum([x for x in range(10)])
一位评论者建议这个:
my_sum = sum(x for x in range(10))
(不同的是刚才说的方括号缺失)。
我感到惊讶的是第二种形式似乎是相同的。 但是,当我试图在第一个工作的其他环境中使用它,它失败:
y = x for x in range(10)
^ SyntaxError !!!
有两种形式相同? 是否有为什么方括号是没有必要的功能的重要原因? 或者这只是我必须知道些什么呢?
这是一个发电机表达。 为了得到它在独立的情况下工作,使用大括号:
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个值。 因此,你应该总是用一台发电机,你不要冒险副作用。
他们是不相同的。
第一种形式,
[x for x in l]
是一个列表理解。 另一种是一个发电机表达,从而写成:
(x for x in l)
它返回一个发电机,而不是一个列表。
如果发电机表达是在函数调用的唯一的参数,其括号可以跳过。
见PEP 289
第一个是列表comprehnsion其中第二个是生成器表达式
(x for x in range(10))
<generator object at 0x01C38580>
>>> a = (x for x in range(10))
>>> sum(a)
45
>>>
使用发电机括号:
>>> y = (x for x in range(10))
>>> y
<generator object at 0x01C3D2D8>
>>>
阅读PEP:289
例如,下面的代码总和将建立在内存广场的完整列表,遍历这些值,并且,当不再需要参考,删除列表:
sum([x*x for x in range(10)])
存储器是通过使用生成器表达式替代保守:
sum(x*x for x in range(10))
随着数据量的增长较大,产生的表达往往会表现得更好,因为他们并没有穷尽缓存和他们让Python来重新使用迭代之间的对象。
使用支具产品发电机:
>>> y = (x for x in range(10))
>>> y
<generator object <genexpr> at 0x00AC3AA8>