Python中的yield浅析


Posted in Python onJune 16, 2014

在介绍yield前有必要先说明下Python中的迭代器(iterator)和生成器(constructor)。

一、迭代器(iterator)

在Python中,for循环可以用于Python中的任何类型,包括列表、元祖等等,实际上,for循环可用于任何“可迭代对象”,这其实就是迭代器

迭代器是一个实现了迭代器协议的对象,Python中的迭代器协议就是有next方法的对象会前进到下一结果,而在一系列结果的末尾是,则会引发StopIteration。任何这类的对象在Python中都可以用for循环或其他遍历工具迭代,迭代工具内部会在每次迭代时调用next方法,并且捕捉StopIteration异常来确定何时离开。

使用迭代器一个显而易见的好处就是:每次只从对象中读取一条数据,不会造成内存的过大开销。

比如要逐行读取一个文件的内容,利用readlines()方法,我们可以这么写:

for line in open("test.txt").readlines():
    print line

这样虽然可以工作,但不是最好的方法。因为他实际上是把文件一次加载到内存中,然后逐行打印。当文件很大时,这个方法的内存开销就很大了。

利用file的迭代器,我们可以这样写:

for line in open("test.txt"):   #use file iterators
    print line

这是最简单也是运行速度最快的写法,他并没显式的读取文件,而是利用迭代器每次读取下一行。

二、生成器(constructor)

生成器函数在Python中与迭代器协议的概念联系在一起。简而言之,包含yield语句的函数会被特地编译成生成器。当函数被调用时,他们返回一个生成器对象,这个对象支持迭代器接口。函数也许会有个return语句,但它的作用是用来yield产生值的。

不像一般的函数会生成值后退出,生成器函数在生成值后会自动挂起并暂停他们的执行和状态,他的本地变量将保存状态信息,这些信息在函数恢复时将再度有效

>>> def g(n):
...     for i in range(n):
...             yield i **2
...
>>> for i in g(5):
...     print i,":",
...
0 : 1 : 4 : 9 : 16 :

要了解他的运行原理,我们来用next方法看看:
>>> t = g(5)
>>> t.next()
0
>>> t.next()
1
>>> t.next()
4
>>> t.next()
9
>>> t.next()
16
>>> t.next()
Traceback (most recent call last):
  File "", line 1, in 
StopIteration

在运行完5次next之后,生成器抛出了一个StopIteration异常,迭代终止。
再来看一个yield的例子,用生成器生成一个Fibonacci数列:

def fab(max):
    a,b = 0,1
    while a < max:
        yield a
        a, b = b, a+b
>>> for i in fab(20):
...     print i,",",
...
0 , 1 , 1 , 2 , 3 , 5 , 8 , 13 ,

看到这里应该就能理解生成器那个很抽象的概念了吧~~
Python 相关文章推荐
sqlalchemy对象转dict的示例
Apr 22 Python
使用Python获取Linux系统的各种信息
Jul 10 Python
vscode 远程调试python的方法
Dec 01 Python
关于Python数据结构中字典的心得
Dec 04 Python
Python绘制3d螺旋曲线图实例代码
Dec 20 Python
获取python文件扩展名和文件名方法
Feb 02 Python
python OpenCV学习笔记直方图反向投影的实现
Feb 07 Python
python连接PostgreSQL数据库的过程详解
Sep 18 Python
完美解决ARIMA模型中plot_acf画不出图的问题
Jun 04 Python
python中如何写类
Jun 29 Python
Python logging模块原理解析及应用
Aug 13 Python
pycharm 实现复制一行的快捷键
Jan 15 Python
python中使用enumerate函数遍历元素实例
Jun 16 #Python
Python中字典(dict)和列表(list)的排序方法实例
Jun 16 #Python
Python实现的几个常用排序算法实例
Jun 16 #Python
Python中文件遍历的两种方法
Jun 16 #Python
Python里隐藏的“禅”
Jun 16 #Python
Python程序设计入门(5)类的使用简介
Jun 16 #Python
Python程序设计入门(4)模块和包
Jun 16 #Python
You might like
php文件上传表单摘自drupal的代码
2011/02/15 PHP
php中转义mysql语句的实现代码
2011/06/24 PHP
CodeIgniter输出中文乱码的两种解决办法
2014/06/12 PHP
thinkphp模板输出技巧汇总
2014/11/24 PHP
PHP正则判断一个变量是否为正整数的方法
2019/02/27 PHP
用Javascript做flash做的事..才完成的一个类.Auntion Action var 0.1
2007/02/23 Javascript
javascript编程起步(第三课)
2007/02/27 Javascript
AngularJS初始化过程分析(引导程序)
2014/12/06 Javascript
JavaScript常用数组算法小结
2016/02/13 Javascript
JavaScript必知必会(七)js对象继承
2016/06/08 Javascript
JS 日期与时间戮相互转化的简单实例
2016/06/22 Javascript
微信小程序 rpx 尺寸单位详细介绍
2016/10/13 Javascript
js省市区级联查询(插件版&amp;无插件版)
2017/03/21 Javascript
利用JS hash制作单页Web应用的方法详解
2017/10/10 Javascript
通过 JS 判断页面是否有滚动条的实现方法
2018/04/05 Javascript
vue 录制视频并压缩视频文件的方法
2018/07/27 Javascript
JavaScript中Array方法你该知道的正确打开方法
2018/09/11 Javascript
element-ui 远程搜索组件el-select在项目中组件化的实现代码
2019/12/04 Javascript
[01:01:31]2018DOTA2亚洲邀请赛3月29日小组赛B组 Mineski VS paiN
2018/03/30 DOTA
[01:10:48]完美世界DOTA2联赛PWL S2 GXR vs PXG 第一场 11.18
2020/11/18 DOTA
Python基础教程之正则表达式基本语法以及re模块
2016/03/25 Python
在Python中,不用while和for循环遍历列表的实例
2019/02/20 Python
Python多线程通信queue队列用法实例分析
2020/03/24 Python
keras自定义损失函数并且模型加载的写法介绍
2020/06/15 Python
Html5新增标签有哪些
2017/04/13 HTML / CSS
HTML5 表单验证失败的提示语问题
2017/07/13 HTML / CSS
PHP解析URL是哪个函数?怎么用?
2013/05/09 面试题
新学期决心书
2014/03/11 职场文书
大学生励志演讲稿
2014/04/25 职场文书
教师自我剖析材料(四风问题)
2014/09/30 职场文书
2014年老干部工作总结
2014/11/21 职场文书
公务员保密工作承诺书
2015/05/04 职场文书
运动会闭幕式通讯稿
2015/07/18 职场文书
CSS实现多个元素在盒子内两端对齐效果
2021/03/30 HTML / CSS
Mysql 如何批量插入数据
2021/04/06 MySQL
Golang 正则匹配效率详解
2021/04/25 Golang