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 相关文章推荐
ubuntu中配置pyqt4环境教程
Dec 27 Python
python 查找文件名包含指定字符串的方法
Jun 05 Python
使用Python更换外网IP的方法
Jul 09 Python
Python和Java的语法对比分析语法简洁上python的确完美胜出
May 10 Python
python实现弹跳小球
May 13 Python
基于tensorflow指定GPU运行及GPU资源分配的几种方式小结
Feb 03 Python
Django-xadmin后台导入json数据及后台显示信息图标和主题更改方式
Mar 11 Python
Python常用外部指令执行代码实例
Nov 05 Python
python 元组和列表的区别
Dec 30 Python
python爬虫爬取淘宝商品比价(附淘宝反爬虫机制解决小办法)
Dec 03 Python
Python项目实战之使用Django框架实现支付宝付款功能
Feb 23 Python
Python使用protobuf序列化和反序列化的实现
May 19 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截取中文字符串的问题
2006/07/12 PHP
《PHP边学边教》(02.Apache+PHP环境配置――下篇)
2006/12/13 PHP
解决GD中文乱码问题
2007/02/14 PHP
Smarty的配置与高级缓存技术分享
2012/06/05 PHP
php简单定时执行任务的实现方法
2015/02/23 PHP
php实现字符串反转输出的方法
2015/03/14 PHP
PHP使用微信开发模式实现搜索已发送图文及匹配关键字回复的方法
2017/09/13 PHP
juqery 学习之三 选择器 简单 内容
2010/11/25 Javascript
JavaScript利用构造函数和原型的方式模拟C#类的功能
2014/03/06 Javascript
JavaScript函数定义的常见注意事项小结
2014/09/16 Javascript
node.js中的fs.readFileSync方法使用说明
2014/12/15 Javascript
学习JavaScript设计模式之观察者模式
2020/04/22 Javascript
Easyui 之 Treegrid 笔记
2016/04/29 Javascript
纯JS实现可拖拽表单的简单实例
2016/09/02 Javascript
AngularJS使用自定义指令替代ng-repeat的方法
2016/09/17 Javascript
BootStrap tab选项卡使用小结
2020/08/09 Javascript
利用D3.js实现最简单的柱状图示例代码
2016/12/09 Javascript
Vuex之理解state的用法实例
2017/04/19 Javascript
单行 JS 实现移动端金钱格式的输入规则
2017/05/22 Javascript
js is_valid_filename验证文件名的函数
2017/07/19 Javascript
JavaScript实现简单轮播图效果
2018/12/01 Javascript
Python统计列表中的重复项出现的次数的方法
2014/08/18 Python
用Python程序抓取网页的HTML信息的一个小实例
2015/05/02 Python
python入门前的第一课 python怎样入门
2018/03/06 Python
Python父目录、子目录的相互调用方法
2019/02/16 Python
python tkinter之顶层菜单、弹出菜单实例
2020/03/04 Python
PyTorch的torch.cat用法
2020/06/28 Python
python如何操作mysql
2020/08/17 Python
世界领先的豪华床上用品供应商之一:Bedeck Home
2019/03/18 全球购物
全球在线商店:BerryLook
2019/04/14 全球购物
FC-Moto英国:欧洲最大的摩托车服装和头盔商店之一
2019/08/25 全球购物
静态变量和实例变量的区别
2015/07/07 面试题
七夕情人节促销方案
2014/06/07 职场文书
离婚撤诉申请书范本
2015/05/18 职场文书
背起爸爸上学观后感
2015/06/08 职场文书
2019经典广告词集锦!
2019/07/02 职场文书