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 相关文章推荐
在Django的模型中执行原始SQL查询的方法
Jul 21 Python
Python编程入门之Hello World的三种实现方式
Nov 13 Python
Python实现图片转字符画的示例代码
Aug 21 Python
Python实现爬虫从网络上下载文档的实例代码
Jun 13 Python
python实现时间o(1)的最小栈的实例代码
Jul 23 Python
详解python使用pip安装第三方库(工具包)速度慢、超时、失败的解决方案
Dec 02 Python
pytorch获取vgg16-feature层输出的例子
Aug 20 Python
Pytorch Tensor 输出为txt和mat格式方式
Jan 03 Python
使用OpenCV对车道进行实时检测的实现示例代码
Jun 19 Python
如何利用python生成MD5并去重
Dec 07 Python
解决Pycharm 运行后没有输出的问题
Feb 05 Python
Python字典和列表性能之间的比较
Jun 07 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操作XML作为数据库的类
2010/12/19 PHP
PHP常用技术文之文件操作和目录操作总结
2014/09/27 PHP
PHP 7.1中AES加解密方法mcrypt_module_open()的替换方案
2017/10/17 PHP
Laravel框架查询构造器 CURD操作示例
2019/09/04 PHP
实现png图片和png背景透明(支持多浏览器)的方法
2009/09/08 Javascript
JQuery 常用操作代码
2010/03/14 Javascript
file控件选择上传文件确定后触发的js事件是哪个
2014/03/17 Javascript
nodejs中转换URL字符串与查询字符串详解
2014/11/26 NodeJs
JavaScript如何调试有哪些建议和技巧附五款有用的调试工具
2015/10/28 Javascript
AngularJS 指令详细介绍
2016/07/27 Javascript
15个非常实用的JavaScript代码片段
2016/12/18 Javascript
Javascript中toFixed计算错误(依赖银行家舍入法的缺陷)解决方法
2017/08/22 Javascript
web3.js增加eth.getRawTransactionByHash(txhash)方法步骤
2018/03/15 Javascript
vue 登录滑动验证实现代码
2018/08/24 Javascript
微信小程序自定义导航栏实例代码
2019/04/05 Javascript
vue实现条件叠加搜索的解决方法
2019/05/28 Javascript
python查找第k小元素代码分享
2013/12/18 Python
linux系统使用python获取cpu信息脚本分享
2014/01/15 Python
提升Python程序运行效率的6个方法
2015/03/31 Python
简单实现python数独游戏
2018/03/30 Python
Django添加feeds功能的示例
2018/08/07 Python
Python Series从0开始索引的方法
2018/11/06 Python
浅谈Python中eval的强大与危害
2019/03/13 Python
Python3实现定时任务的四种方式
2019/06/03 Python
python中pip的使用和修改下载源的方法
2019/07/08 Python
python excel转换csv代码实例
2019/08/26 Python
Python中函数的返回值示例浅析
2019/08/28 Python
Django使用rest_framework写出API
2020/05/21 Python
Jacadi Paris英国官网:法国童装品牌
2019/08/09 全球购物
高中同学聚会邀请函
2014/01/11 职场文书
征婚广告词
2014/03/17 职场文书
仓库文员岗位职责
2014/04/06 职场文书
有关九一八事变的演讲稿
2014/09/14 职场文书
2015年银行客户经理工作总结
2015/04/01 职场文书
2015年宣传部个人工作总结
2015/05/14 职场文书
初级职称评定工作总结
2015/08/13 职场文书