Python 'for' 语法:块代码与单行生成器表达式



我熟悉块代码上下文中的for循环。 例如:

for c in "word":
print c

我刚刚遇到了一些以不同方式使用for的例子。它们不是以for语句开头,而是在表达式的末尾标记它(并且不涉及缩进的代码块)。例如:

sum(x*x for x in range(10))

谁能指出我一些概述for使用的文档?我已经能够找到例子,但没有解释。我能找到的所有for文档都描述了以前的用法(块代码示例)。我什至不确定该怎么称呼这种用途,所以如果我的问题标题不清楚,我深表歉意。

你所指的是Python中的Generator。看看: -

  • http://wiki.python.org/moin/Generators
  • http://www.python.org/dev/peps/pep-0255/
  • http://docs.python.org/whatsnew/2.5.html#pep-342-new-generator-features

请参阅文档: -Generator Expression其中包含与您发布的完全相同的示例

从文档: -

生成器是用于创建迭代器的简单而强大的工具。他们 像常规函数一样编写,但使用 yield 语句 每当他们想要返回数据时。每次调用 next() 时, 生成器从中断的地方恢复(它会记住所有数据值 以及上次执行的语句)

生成器类似于您与square brackets一起使用的List Comprehension而不是brackets,但它们的内存效率更高。它们不会同时返回结果的完整list,但会返回生成器对象。每当在generator对象上调用next()时,生成器都会使用yield返回下一个值。

上述代码的List Comprehension如下所示: -

[x * x for x in range(10)]

您还可以添加条件以在 for 末尾筛选出结果。

[x * x for x in range(10) if x % 2 != 0]

这将返回 1 到 5 范围内的numbers乘以 2 的列表,如果数字不能被 2 整除。

描述yield用法的Generators示例可以是: -

def city_generator():
yield("Konstanz")
yield("Zurich")
yield("Schaffhausen")
yield("Stuttgart")
>>> x = city_generator()
>>> x.next()
Konstanz
>>> x.next()
Zurich
>>> x.next()
Schaffhausen
>>> x.next()
Stuttgart
>>> x.next()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration

所以,你可以看到,每次调用next()都会在generator中执行下一个yield(),最后它会抛出StopIteration

这些是生成器表达式,它们与列表推导有关

列表推导式允许轻松创建列表。例如,如果你想创建一个完美正方形的列表,你可以这样做:

>>> squares = []
>>> for x in range(10):
...     squares.append(x**2)
...
>>> squares
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

但相反,您可以使用列表理解:

squares = [x**2 for x in range(10)]

生成器表达式类似于列表推导式,只是它们返回生成器对象而不是列表。您可以采用与列表推导类似的方式迭代此生成器对象,但不必像在列表推导式中创建列表那样一次将整个列表存储在内存中。

生成器表达式的文档在这里 https://www.python.org/dev/peps/pep-0289/以下是使用生成器表达式的代码。

list(x**2 for x in range(0,10))

您的特定示例称为生成器表达式。列表推导式、字典推导式和集合推导式在含义上相似(不同的结果类型,生成器表达式是惰性的),并且具有相同的语法,模数位于其他类型的括号内,并且在字典推导的情况下具有expr1: expr2而不是单个表达式(在您的示例中为 x*x)。

最新更新