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中使用HTMLParser解析HTML的教程
Apr 29 Python
Python3连接MySQL(pymysql)模拟转账实现代码
May 24 Python
Python实现脚本锁功能(同时只能执行一个脚本)
May 10 Python
python实现对excel进行数据剔除操作实例
Dec 07 Python
Python实现七彩蟒蛇绘制实例代码
Jan 16 Python
python判断计算机是否有网络连接的实例
Dec 15 Python
Python面向对象类编写细节分析【类,方法,继承,超类,接口等】
Jan 05 Python
12个Python程序员面试必备问题与答案(小结)
Jun 24 Python
Python 转换RGB颜色值的示例代码
Oct 13 Python
keras 权重保存和权重载入方式
May 21 Python
Python将QQ聊天记录生成词云的示例代码
Feb 10 Python
Python 机器学习工具包SKlearn的安装与使用
May 14 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 checkdate、getdate等日期时间函数操作详解
2010/03/11 PHP
php mssql扩展SQL查询中文字段名解决方法
2012/10/15 PHP
js prototype 格式化数字 By shawl.qiu
2007/04/02 Javascript
输入框的字数时时统计—关于 onpropertychange 和 oninput 使用
2011/10/21 Javascript
js报$ is not a function 的问题的解决方法
2014/01/20 Javascript
jquery中的ajax方法怎样通过JSONP进行远程调用
2014/05/04 Javascript
js实现文字垂直滚动和鼠标悬停效果
2015/12/31 Javascript
ichart.js绘制虚线、平均分虚线效果的实现代码
2016/05/05 Javascript
利用JavaScript判断浏览器类型及版本
2016/08/23 Javascript
javascript 定时器工作原理分析
2016/12/03 Javascript
三种方式实现瀑布流布局
2017/02/10 Javascript
Bootstrap3下拉菜单的实现
2017/02/22 Javascript
Bootstrap modal 多弹窗之叠加关闭阴影遮罩问题的解决方法
2017/02/27 Javascript
BootStrap 表单控件之单选按钮水平排列
2017/05/23 Javascript
对Vue beforeRouteEnter 的next执行时机详解
2018/08/25 Javascript
es6函数中的作用域实例分析
2020/04/18 Javascript
uni-app微信小程序登录授权的实现
2020/05/22 Javascript
vue缓存之keep-alive的理解和应用详解
2020/11/02 Javascript
通过数据库对Django进行删除字段和删除模型的操作
2015/07/21 Python
python实现发送和获取手机短信验证码
2016/01/15 Python
Python检测网站链接是否已存在
2016/04/07 Python
SQLite3中文编码 Python的实现
2017/01/11 Python
Django添加sitemap的方法示例
2018/08/06 Python
python hbase读取数据发送kafka的方法
2018/12/27 Python
使用PYTHON解析Wireshark的PCAP文件方法
2019/07/23 Python
python 爬取疫情数据的源码
2020/02/09 Python
Osklen官方在线商店:巴西服装品牌
2019/04/25 全球购物
党代会心得体会
2014/09/04 职场文书
“六查”、“三学”、“三干”查摆问题整改措施
2014/09/27 职场文书
人民调解协议书范本
2014/10/11 职场文书
思想道德自我评价2015
2015/03/09 职场文书
推荐信范文大全
2015/03/27 职场文书
网络安全倡议书(3篇)
2019/09/18 职场文书
浅析InnoDB索引结构
2021/04/05 MySQL
总结Java对象被序列化的两种方法
2021/06/30 Java/Android
Go语言基础切片的创建及初始化示例详解
2021/11/17 Golang