Python基础教程 创建生成器

9.7.1 创建生成器

生成器创建起来与函数一样简单。你现在肯定厌烦了老套的斐波那契数列,所以下面换换口味,创建一个将嵌套列表展开的函数。这个函数将一个类似于下面的列表作为参数:

nested = [[1, 2], [3, 4], [5]]

换而言之,这是一个列表的列表。函数应按顺序提供这些数字,下面是一种解决方案:

def flatten(nested):

for sublist in nested:

for element in sublist:

yield element

这个函数的大部分代码都很简单。它首先迭代所提供嵌套列表中的所有子列表,然后按顺序迭代每个子列表的元素。倘若最后一行为print(element),这个函数将容易理解得多,不是吗?

在这里,你没有见过的是yield语句。包含yield语句的函数都被称为生成器。这可不仅仅是名称上的差别,生成器的行为与普通函数截然不同。差别在于,生成器不是使用return返回一个值,而是可以生成多个值,每次一个。每次使用yield生成一个值后,函数都将冻结,即在此停止执行,等待被重新唤醒。被重新唤醒后,函数将从停止的地方开始继续执行。

为使用所有的值,可对生成器进行迭代。

>>> nested = [[1, 2], [3, 4], [5]]

>>> for num in flatten(nested):

... print(num)

...

1

2

3

4

5

>>> list(flatten(nested))

[1, 2, 3, 4, 5]

简单生成器

在Python 2.4中,引入了一个类似于列表推导(参见第5章)的概念: 生成器推导(也叫生成器表达式)。其工作原理与列表推导相同,但不是创建一个列表(即不立即执行循环),而是返回一个生成器,让你能够逐步执行计算。

>>> g = ((i + 2) ** 2 for i in range(2, 27))

>>> next(g)

16

如你所见,不同于列表推导,这里使用的是圆括号。在像这样的简单情形下,还不如使

用列表推导;但如果要包装可迭代对象(可能生成大量的值),使用列表推导将立即实例化一

个列表,从而丧失迭代的优势。

另一个好处是,直接在一对既有的圆括号内(如在函数调用中)使用生成器推导时,无需

再添加一对圆括号。换而言之,可编写下面这样非常漂亮的代码:

sum(i ** 2 for i in range(10))

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20181220G06JQW00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券