生成器详解
来源:互联网 发布:删除json里的一个对象 编辑:程序博客网 时间:2024/06/01 08:12
可迭代对象(iterable) 与 迭代器(iterator)
关系如下图:
对一个iterable用for … in …进行迭代时,实际是先通过调用iter()方法得到一个iterator,假设叫做X。然后循环地调用X的next()方法取得每一次的值,直到iterator为空,返回的StopIteration作为循环结束的标志。for … in … 会自动处理StopIteration异常,从而避免了抛出异常而使程序中断。
生成器
生成器,就是带有yield的函数。包含生成器函数和生成器表达式(形如(elem for elem in [1, 2, 3])的表达式)
生成器函数(generator function)的返回值是生成器、迭代器(generator iterator)
生成器表达式(generator expression)的返回值是迭代器(iterator)
示例代码如下:
>>> a = (elem for elem in [1, 2, 3])>>> a<generator object <genexpr> at 0x7f0d23888048>>>> def fib():... a, b = 0, 1... while True:... yield b... a, b = b, a + b...>>> fib<function fib at 0x7f0d238796a8>>>> b = fib()<generator object fib at 0x7f0d20bbfea0>
综上:生成器(generator)就是迭代器(iterator)的一种,以更优雅的方式实现的iterator,而且完全可以像使用iterator一样使用generator。当然除了定义,定义一个iterator,你需要分别实现_ _ iter _ _ ()方法和 _ _ next_ _()方法,但generator只需要一个小小的yield
生成器的调用方法:
示例代码:
>>> def gen():... while True:... s = yield... print(s)...>>> g = gen()>>> g.send("kissg")Traceback (most recent call last): File "<stdin>", line 1, in <module>TypeError: can't send non-None value to a just-started generator>>> next(g)>>> g.send("kissg")kissg
从上述例子可以看出,generator 其实有2种调用方法(恢复执行),即通过send(value)方法将value作为yield表达式的当前值。你可以用该值再对其他变量进行赋值。当我们调用send(value)方法时,generator正由于yield的缘故被暂停了。此时,send(value)方法传入的值作为yield表达式的值,函数中又将该值赋给了变量s,然后print函数打印s,循环再遇到yield,暂停返回。
调用send(value)时要注意,要确保 generator 是在yield处被暂停了,如此才能向yield表达式传值,否则将会报错(如上所示),可通过next()方法或send(None)使generator执行到yield。
再来看一段yield更复杂的用法,或许能加深你对generator的next()与send(value)的理解。
>>> def echo(value=None):... while 1:... value = (yield value)... print("The value is", value)... if value:... value += 1...>>> g = echo(1)>>> next(g)1>>> g.send(2)The value is 23>>> g.send(5)The value is 56>>> next(g)The value is None
小结
- 可迭代对象(Iterable)是实现了iter()方法的对象,通过调用iter()方法可以获得一个迭代器(Iterator)。
- 迭代器(Iterator)是实现了iter()和next()的对象。
- for … in …的迭代,实际是将可迭代对象转换成迭代器,再重复调用next()方法实现的。
- 生成器(generator)是一个特殊的迭代器,它的实现更简单优雅。
- yield是生成器实现next()方法的关键。它作为生成器执行的暂停恢复点,可以对yield表达式进行赋值,也可以将yield表达式的值返回。
参考文档:http://kissg.me/2016/04/09/python-generator-yield/
- 生成器详解
- Hibernate主键生成器详解
- python生成器详解
- 详解生成器、迭代器
- Python 生成器详解 generator
- python生成器详解
- Python 生成器原理详解
- Python 生成器原理详解
- hibernate中id生成器详解
- python 迭代器与生成器 详解
- Python生成器(Generator)详解
- Python生成器(Generator)详解
- mybatis代码生成器配置文件详解
- hibernate自定义主键生成器详解
- python 迭代器与生成器 详解
- RAML文档生成器raml2html详解
- Python生成器(Generator)详解
- 生成器
- 如何快速成为一个领域的专家?
- id唯一标识
- RabbitMQ官方文档翻译之Routing(四)
- E
- 剑指offer--合并两个排序的链表
- 生成器详解
- Redis的数据类型
- Linux 平台下用CMake搭建Eclipse CDT工程
- Linux基础入门指令
- RabbitMQ官方文档翻译之Topics(五)
- ORACLE特殊数据查询技术
- 机器学习和深度学习的最佳框架大比拼
- Android 短信发送器
- 【数据结构上机作业】输入一批学生的成绩(至少包括学生学号、姓名、课程成绩),用单链表存储,输出大于平均成绩的学生信息。