解析Python中的生成器及其与迭代器的差异


Posted in Python onJune 20, 2016

生成器
生成器是一种迭代器,是一种特殊的函数,使用yield操作将函数构造成迭代器。普通的函数有一个入口,有一个返回值;当函数被调用时,从入口开始执行,结束时返回相应的返回值。生成器定义的函数,有多个入口和多个返回值;对生成器执行next()操作,进行生成器的入口开始执行代码,yield操作向调用者返回一个值,并将函数挂起;挂起时,函数执行的环境和参数被保存下来;对生成器执行另一个next()操作时,参数从挂起状态被重新调用,进入上次挂起的执行环境继续下面的操作,到下一个yield操作时重复上面的过程。Python的循环操作与C语言的实现不同,如果使用List等数据结构需要耗费大量的内容;循环操作中使用生成器只需要在内存中实例化一个对象,可以减少内存占用,提高循环操作的执行速度。

>>>def myG():
...  yield 1
...  yield 2
...  yield 3
...
>>>g=myG()
>>>next(g)
1
>>>next(g)
2
>>>next(g)
3
>>>next(g)
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
StopIteration
>>>g2=myG()
>>>for i in g2:
...  print(i)
1
2
3

生成器表达式
for...[if]...语句可以简洁的构建一个List,同时也可以用来构建生成器。

>>>a=[7,8,9]
>>>b=[i**2 for i in a]
>>>b
[49, 64, 81]
>>>ib=(i**2 for i in a)
>>>ib
<generator object <genexpr> at 0x7f72291217e0>
>>>next(ib)
49
>>>next(ib)
64
>>>next(ib)
81
>>>next(ib)
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
StopIteration

迭代器(Iterator)与生成器(Generator)的区别
迭代器是一个更抽象的概念,任何对象,如果它的类有next方法(next python3)和iter方法返回自己本身。

每个生成器都是一个迭代器,但是反过来不行。通常生成器是通过调用一个或多个yield表达式构成的函数s生成的。同时满足迭代器的定义。

当你需要一个类除了有生成器的特性之外还要有一些自定义的方法时,可以使用自定义的迭代器,一般来说生成器更方便,更简单。

def squares(start, stop):
  for i in xrange(start, stop):
    yield i*i

等同于生成器表达式:

(i*i for i in xrange(start, stop))

列表推倒式是:

[i*i for i in xrange(start, stop)]

如果是构建一个自定义的迭代器:

class Squares(object):
  def __init__(self, start, stop):
    self.start = start
    self.stop = stop
  def __iter__(self):
    return self
  def next(self):
    if self.start >= self.stop:
      raise StopIteration
    current = self.start * self.start
    self.start += 1
    return current

此时,你还可以定义自己的方法如:

def current(self):
  return self.start

两者的相同点:对象迭代完后就不能重写迭代了。

Python 相关文章推荐
python基础教程之自定义函数介绍
Aug 29 Python
Python 闭包的使用方法
Sep 07 Python
python中csv文件的若干读写方法小结
Jul 04 Python
python版DDOS攻击脚本
Jun 12 Python
详解Python利用random生成一个列表内的随机数
Aug 21 Python
Django文件上传与下载(FileFlid)
Oct 06 Python
Django实现基于类的分页功能
Oct 31 Python
如何使用python实现模拟鼠标点击
Jan 06 Python
将matplotlib绘图嵌入pyqt的方法示例
Jan 08 Python
Django-migrate报错问题解决方案
Apr 21 Python
python对接ihuyi实现短信验证码发送
May 10 Python
Pycharm配置autopep8实现流程解析
Nov 28 Python
Python判断列表是否已排序的各种方法及其性能分析
Jun 20 #Python
Python编程中装饰器的使用示例解析
Jun 20 #Python
12步入门Python中的decorator装饰器使用方法
Jun 20 #Python
深入学习Python中的装饰器使用
Jun 20 #Python
Python中Iterator迭代器的使用杂谈
Jun 20 #Python
实例讲解Python编程中@property装饰器的用法
Jun 20 #Python
Python的包管理器pip更换软件源的方法详解
Jun 20 #Python
You might like
php&amp;mysql 日期操作小记
2012/02/27 PHP
yii2 开发api接口时优雅的处理全局异常的方法
2019/05/14 PHP
PHP常用字符串输出方法分析(echo,print,printf及sprintf)
2021/03/09 PHP
jquery实现图片裁剪思路及实现
2013/08/16 Javascript
JSON.stringify转换JSON时日期时间不准确的解决方法
2014/08/08 Javascript
JS 实现列表与多选框选择附预览动画
2014/10/29 Javascript
jQuery简单实现QQ空间点赞已经取消点赞
2015/04/02 Javascript
简单谈谈Javascript中类型的判断
2015/10/19 Javascript
整理Javascript流程控制语句学习笔记
2015/11/29 Javascript
JavaScript优化专题之Loading and Execution加载和运行
2016/01/20 Javascript
JS功能代码集锦
2016/05/04 Javascript
浅析js绑定事件的常用方法
2016/05/15 Javascript
Vue实例简单方法介绍
2017/01/20 Javascript
实例解析js中try、catch、finally的执行规则
2017/02/24 Javascript
vue2.0中click点击当前li实现动态切换class
2017/06/21 Javascript
Bootstrap Tooltip显示换行和左对齐的解决方案
2017/10/11 Javascript
webpack external模块的具体使用
2018/03/10 Javascript
mpvue 单文件页面配置详解
2018/12/02 Javascript
three.js实现圆柱体
2018/12/30 Javascript
如何优雅地在vue中添加权限控制示例详解
2019/03/07 Javascript
jQuery实现checkbox全选、反选及删除等操作的方法详解
2019/08/02 jQuery
Vuex的各个模块封装的实现
2020/06/05 Javascript
[00:37]DOTA2上海特级锦标赛 Secert 战队宣传片
2016/03/03 DOTA
[02:16]2018年度CS GO最具人气选手-完美盛典
2018/12/16 DOTA
python代码 FTP备份交换机配置脚本实例解析
2019/08/01 Python
将python2.7添加进64位系统的注册表方式
2019/11/20 Python
Python与C/C++的相互调用案例
2021/03/04 Python
解决canvas转base64/jpeg时透明区域变成黑色背景的方法
2016/10/23 HTML / CSS
皇家道尔顿官网:Royal Doulton
2017/12/06 全球购物
意大利在线高尔夫商店:Online Golf
2021/03/09 全球购物
垃圾回收的优点和原理
2014/05/16 面试题
Java中的异常处理机制的简单原理和应用
2013/04/27 面试题
我为自己代言广告词
2014/03/18 职场文书
建国70周年的心得体会(2篇)
2019/09/20 职场文书
使用golang编写一个并发工作队列
2021/05/08 Golang
Python基础知识学习之类的继承
2021/05/31 Python