解析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中文问题解决方法(总结了多位前人经验,初学者必看)
Mar 13 Python
python实现获取客户机上指定文件并传输到服务器的方法
Mar 16 Python
Python中文分词实现方法(安装pymmseg)
Jun 14 Python
python 使用get_argument获取url query参数
Apr 28 Python
python读文件保存到字典,修改字典并写入新文件的实例
Apr 23 Python
浅谈python在提示符下使用open打开文件失败的原因及解决方法
Nov 30 Python
python 实现查找文件并输出满足某一条件的数据项方法
Jun 12 Python
python__new__内置静态方法使用解析
Jan 07 Python
Python换行与不换行的输出实例
Feb 19 Python
python 爬虫 实现增量去重和定时爬取实例
Feb 28 Python
python 中 .py文件 转 .pyd文件的操作
Mar 04 Python
Python OpenCV实现图形检测示例详解
Apr 08 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下使用iconv需要注意的问题
2010/11/20 PHP
用PHP读取和编写XML DOM的实现代码
2011/02/03 PHP
Smarty变量调节器失效的解决办法
2014/08/20 PHP
老司机传授Ubuntu下Apache+PHP+MySQL环境搭建攻略
2016/03/20 PHP
php中mkdir()函数的权限问题分析
2016/09/24 PHP
阿里对象存储OSS在laravel框架中的使用方法
2019/10/13 PHP
VSCode+PHPstudy配置PHP开发环境的步骤详解
2020/08/20 PHP
JavaScript 页面编码与浏览器类型判断代码
2010/06/03 Javascript
Jquery.LazyLoad.js修正版下载,实现图片延迟加载插件
2011/03/12 Javascript
jQuery显示和隐藏 常用的状态判断方法
2015/01/29 Javascript
JavaScript事件委托技术实例分析
2015/02/06 Javascript
jquery插件jquery.nicescroll实现图片无滚动条左右拖拽的方法
2015/08/10 Javascript
js添加绑定事件的方法
2016/05/15 Javascript
利用nodejs监控文件变化并使用sftp上传到服务器
2017/02/18 NodeJs
老生常谈javascript中逻辑运算符&amp;&amp;和||的返回值问题
2017/04/13 Javascript
nodejs dgram模块广播+组播的实现示例
2019/11/04 NodeJs
vue 组件销毁并重置的实现
2020/01/13 Javascript
python 写的一个爬虫程序源码
2016/02/28 Python
设计模式中的原型模式在Python程序中的应用示例
2016/03/02 Python
python ddt实现数据驱动
2018/03/14 Python
浅谈Tensorflow由于版本问题出现的几种错误及解决方法
2018/06/13 Python
linux安装Python3.4.2的操作方法
2018/09/28 Python
python基于socket进行端口转发实现后门隐藏的示例
2019/07/25 Python
使用Bazel编译TensorBoard教程
2020/02/15 Python
jupyter lab的目录调整及设置默认浏览器为chrome的方法
2020/04/10 Python
CSS3 特效范例整理
2011/08/22 HTML / CSS
css3选择器基本介绍
2014/12/15 HTML / CSS
CSS3实现鼠标悬停显示扩展内容
2016/08/24 HTML / CSS
伦敦眼门票在线预订:London Eye
2018/05/31 全球购物
活动总结怎么写啊
2014/05/07 职场文书
采购部长岗位职责
2014/06/13 职场文书
2014年村计划生育工作总结
2014/11/14 职场文书
党员个人总结范文
2015/02/14 职场文书
小学大队委竞选口号
2015/12/25 职场文书
2016年党员承诺书范文
2016/03/24 职场文书
2016年企业安全生产月活动总结
2016/04/06 职场文书