生成器表达式可以理解为列表推导的惰性版本:不会迫切地构建列表,而是返回一个生成器,按需惰性生成元素。
也就是说,如果列表推导是制造列表的工厂,那么生成器表达式就是制造生成器的工厂。

示例 14-8 先在列表推导中使用 gen_AB 生成器函数,然后在生成器表达式中使用

>>> def gen_AB():  # ➊
... print('start')
... yield 'A'
... print('continue')
... yield 'B'
... print('end.')
...
>>> res1 = [x*3 for x in gen_AB()] # ➋
start
continue
end.
>>> for i in res1: # ➌
... print('-->', i)
...
--> AAA
--> BBB
>>> res2 = (x*3 for x in gen_AB()) # ➍
>>> res2 # ➎
<generator object <genexpr> at 0x10063c240>
>>> for i in res2: # ➏
... print('-->', i)
...
start
--> AAA
continue
--> BBB
end.

❶ gen_AB 函数与示例 14-6 中的一样。
❷ 列表推导迫切地迭代 gen_AB() 函数生成的生成器对象产出的元素:'A' 和 'B'。注意,下面的输出是 start、continue 和 end.。
❸ 这个 for 循环迭代列表推导生成的 res1 列表。
❹ 把生成器表达式返回的值赋值给 res2。只需调用 gen_AB() 函数,虽然调用时会返回一个生成器,但是这里并不使用。
❺ res2 是一个生成器对象。
❻ 只有 for 循环迭代 res2 时,gen_AB 函数的定义体才会真正执行。for 循环每次迭代时会隐式调用 next(res2),前进到 gen_AB 函数中的下一个 yield 语句。
注意,gen_AB 函数的输出与 for 循环中print 函数的输出夹杂在一起。

可以看出,生成器表达式会产出生成器,因此可以使用生成器表达式进一步减少 Sentence 类的代码,如示例 14-9 所示。

示例 14-9 sentence_genexp.py:使用生成器表达式实现 Sentence类

import re
import reprlib RE_WORD = re.compile('\w+') class Sentence: def __init__(self, text):
self.text = text def __repr__(self):
return 'Sentence(%s)' % reprlib.repr(self.text) def __iter__(self):
return (match.group() for match in RE_WORD.finditer(self.text))

与示例 14-7 唯一的区别是 __iter__ 方法,这里不是生成器函数了(没有 yield),而是使用生成器表达式构建生成器,然后将其返回。
不过,最终的效果一样:调用 __iter__ 方法(指代Sentence的 __iter__ 方法)会得到一个生成器对象。

最新文章

  1. IoC在ASP.NET Web API中的应用
  2. vi command
  3. rsync 通过 ssh 上传文件
  4. 关于javascript tween的学后小感想
  5. 关于hr标签兼容个浏览器的代码
  6. 【原创】-- uboot,kennel,fs,rootfs 编译制作
  7. Java httpclient请求,解决乱码问题
  8. ChartDirector应用笔记(三)
  9. C#→关于System.Data.Linq下的Table&lt;TEntity&gt; 泛型类 的问题
  10. PAT乙级真题1003. 我要通过!(20)(解题)
  11. 初识 Lucene
  12. About &#39;atoi&#39;
  13. Effect of Switchovers, Failovers, and Control File Creation on Backups
  14. Android开发中用到的框架、库介绍
  15. android 更改USB显示名称
  16. Visual Studio 单元测试之三---压力测试
  17. MySQL里创建外键时错误的解决
  18. thinkphp无法加载控制器:Admin
  19. NFC Spy:基于Android 4.4及以上手机的非接智能卡跟踪仪
  20. javascript和c#aes加密方法互解

热门文章

  1. CenterOS7 网络配置
  2. PHP 实现过滤参数字符的方法
  3. (数据科学学习手札87)利用adjustText解决matplotlib文字标签遮挡问题
  4. 关于JSON数据体积优化的一点小心得
  5. 刷一遍《剑指Offer》,你还需要这些知识!(一刷)
  6. docker 容器命令
  7. CSS小功能实现
  8. mermaid使用简介(画论文插图的一种解决方案)
  9. 漏洞复现-Office远程代码执行漏洞 (CVE-2017-11882&amp;CVE-2018-0802)
  10. opencv C++ Mat构造函数