Python生成器generator原理及用法解析


Posted in Python onJuly 20, 2020

前言

生成器generator

生成器的本质是一个迭代器(iterator)

要理解生成器,就要在理解一下迭代,可迭代对象,迭代器,这三个概念

Python生成器generator简介

iteration, iterable, iterator

迭代(iteration):在python中迭代通常是通过for...in...来实现的.而且只要是可迭代对象iterable,都能进行迭代.

可迭代对象(iterable):Python中的任意的对象,只要它定义了可以返回一个迭代器的 __iter__方法,或者定义了可以支持下标索引的__getitem __方法,那么它就是一个可迭代对象。简单说,可迭代对象就是能提供迭代器的任意对象.返回的是一个iterator 对象.官方解释

迭代器(iterator ) : 简单的说,迭代器就是实现了iterator.__iter__() 和iterator.__next__() 的对象,iterator.__iter__()方法返回的是iterator对象本身.根据官方的说法,正是这个方法,实现了for ... in ...语句.而iterator.__next__()是iterator区别于iterable的关键了,它允许我们显式地获取一个元素.当调用next()方法时,实际上产生了2个操作:

更新iterator状态,令其指向后一项,以便下一次调用,每一个值过后,指针移动到下一位,对iterator遍历完后,其变成了一个空的容器,但不是None ,需要注意的是,迭代结束后,指针不会自动返回到首位,而是依旧停留在末位置,想要在开始,需要重新载入迭代对象.

实例理解:

>>> from collections import Iterable, Iterator
 >>> a = [1,2,3]  # 众所周知,list是一个iterable
 >>> b = iter(a)  # 通过iter()方法,得到iterator,iter()实际上调用了__iter__(),
 >>> isinstance(a, Iterable)
 True
 >>> isinstance(a, Iterator)
 False
 >>> isinstance(b, Iterable)
 True
 >>> isinstance(b, Iterator)
 True

可见,itertor 一定是iterable ,但iterable不一定是itertor

>>> dir(a)
 ['__add__','__class__','__contains__','__delattr__','__delitem__','__dir__','__doc__','__eq__','__format__','__ge__','__getattribute__','__getitem__','__gt__','__hash__','__iadd__','__imul__','__init__','__iter__','__le__','__len__','__lt__','__mul__','__ne__','__new__','__reduce__','__reduce_ex__','__repr__', '__reversed__','__rmul__', '__setattr__','__setitem__','__sizeof__','__str__', '__subclasshook__','append','clear' 'copy','count','extend','index','insert', 'pop','remove', 'reverse','sort']
 
 >>>dir(b)
 ['__class__','__delattr__', '__dir__', '__doc__','__eq__', '__format__','__ge__' ,'__getattribute__', '__gt__','__hash__','__init__','__iter__','__le__','__length_hint__',
 '__lt__','__ne__','__new__','__next__','__reduce__','__reduce_ex__','__repr__','__setattr__', '__setstate__','__sizeof__','__str__','__subclasshook__']

可以看到迭代器具有__next__ 这个方法,可迭代对象具有__getitem__

迭代器是消耗型的,随着指针的移动,遍历完毕以后,就为空,但是不是None

>>> c = list(b)
 >>> c
 [1, 2, 3]
 >>> d = list(b)
 >>> d
 []
 
 
 # 空的iterator并不等于None.
 >>> if b:
 ...  print(1)
 ...
 1
 >>> if b == None:
 ...  print(1)
 ...

使用迭代器的内置方法 __next__ 和 next() 方法,遍历元素

In [73]: e = iter(a)
 
 In [74]: next(e)
 Out[74]: 1
 
 In [75]: e.__next__
 Out[75]: <method-wrapper '__next__' of list_iterator object at 0x7f05571c8518>
 
 In [76]: e.__next__()
 Out[76]: 2
 
 In [77]: e.__next__()
 Out[77]: 3
 
 In [78]: e.__next__()
 ---------------------------------------------------------------------------
 StopIteration               Traceback (most recent call last)
 <ipython-input-78-6024b5bd9bd2> in <module>()
 ----> 1 e.__next__()
 StopIteration:

当遍历完毕时,会返回一个StopIteration 的错误.

for...in.... 遍历迭代

当我们对一个iterable 使用for ....in... 进行遍历时,实际上是想调用iter() 方法得到一个iterator ,假设为x ,然后循环的调用x 的__next__() (next())方法,取得每一次的值,直到iterator为空,返回StopIteration 作为循环的结束的标准.for....in...会自动处理 StopIteration 异常,从而避免了抛出异常,从而使程序中断.流程图为:

x = [1, 2, 3]
for i in x:
print(x)

Python生成器generator原理及用法解析

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python 排序算法总结及实例详解
Sep 28 Python
Python 3中print函数的使用方法总结
Aug 08 Python
Request的中断和ErrorHandler实例解析
Feb 12 Python
详解Django解决ajax跨域访问问题
Aug 24 Python
Python产生Gnuplot绘图数据的方法
Nov 09 Python
Python基础之条件控制操作示例【if语句】
Mar 23 Python
详解Python的数据库操作(pymysql)
Apr 04 Python
使用Python制作一个打字训练小工具
Oct 01 Python
Python 生成一个从0到n个数字的列表4种方法小结
Nov 28 Python
Python图像处理库PIL的ImageFilter模块使用介绍
Feb 26 Python
基于python SMTP实现自动发送邮件教程解析
Jun 02 Python
pandas求平均数和中位数的方法实例
Aug 04 Python
Win10环境中如何实现python2和python3并存
Jul 20 #Python
python和go语言的区别是什么
Jul 20 #Python
Python基础教程(一)——Windows搭建开发Python开发环境
Jul 20 #Python
Python字典fromkeys()方法使用代码实例
Jul 20 #Python
Python爬虫设置ip代理过程解析
Jul 20 #Python
Python如何使用27行代码绘制星星图
Jul 20 #Python
tensorflow基于CNN实战mnist手写识别(小白必看)
Jul 20 #Python
You might like
php+mysql实现无限级分类 | 树型显示分类关系
2006/11/19 PHP
关于Appserv无法打开localhost问题的解决方法
2009/10/16 PHP
PHP递归返回值时出现的问题解决办法
2013/02/19 PHP
PHP实现数组递归转义的方法
2014/08/28 PHP
PHP curl 抓取AJAX异步内容示例
2014/09/09 PHP
jQuery 遍历json数组的实现代码
2020/09/22 Javascript
JavaScript 比较时间大小的代码
2010/04/24 Javascript
Jquery倒数计时按钮setTimeout的实例代码
2013/07/04 Javascript
jquery.uploadify插件在chrome浏览器频繁崩溃解决方法
2015/03/01 Javascript
jQuery实时显示鼠标指针位置和键盘ASCII码
2016/03/28 Javascript
JavaScript的Ext JS框架中的GridPanel组件使用指南
2016/05/21 Javascript
JavaScript操作表单实例讲解(上)
2016/06/20 Javascript
JS基于递归算法实现1,2,3,4,5,6,7,8,9倒序放入数组中的方法
2017/01/03 Javascript
js 奇葩技巧之隐藏代码
2017/08/11 Javascript
Bootstrap3.3.7导航栏下拉菜单鼠标滑过展开效果
2017/10/31 Javascript
通过nodejs 服务器读取HTML文件渲染到页面的方法
2018/05/17 NodeJs
Websocket 向指定用户发消息的方法
2020/01/09 Javascript
python代码 if not x: 和 if x is not None: 和 if not x is None:使用介绍
2016/09/21 Python
Python模糊查询本地文件夹去除文件后缀的实例(7行代码)
2017/11/09 Python
python之验证码生成(gvcode与captcha)
2019/01/02 Python
pycharm中显示CSS提示的知识点总结
2019/07/29 Python
python自动化工具之pywinauto实例详解
2019/08/26 Python
python 初始化一个定长的数组实例
2019/12/02 Python
如何基于Python实现电子邮件的发送
2019/12/16 Python
详解python tkinter包获取本地绝对路径(以获取图片并展示)
2020/09/04 Python
python 实现socket服务端并发的四种方式
2020/12/14 Python
Canvas实现保存图片到本地的示例代码
2018/06/28 HTML / CSS
会计实习生工作总结的自我评价
2013/10/07 职场文书
优秀村官事迹材料
2014/01/10 职场文书
校园绿化美化方案
2014/06/08 职场文书
化工工艺设计求职信
2014/06/25 职场文书
行政专员岗位职责范本
2014/08/26 职场文书
个人四风问题原因分析及整改措施
2014/09/28 职场文书
企业团队精神心得体会
2016/01/19 职场文书
Vue中foreach数组与js中遍历数组的写法说明
2021/06/05 Vue.js
如何用python清洗文件中的数据
2021/06/18 Python