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 相关文章推荐
把项目从Python2.x移植到Python3.x的经验总结
Apr 20 Python
Python max内置函数详细介绍
Nov 17 Python
分享一个可以生成各种进制格式IP的小工具实例代码
Jul 28 Python
Python实现1-9数组形成的结果为100的所有运算式的示例
Nov 03 Python
30秒轻松实现TensorFlow物体检测
Mar 14 Python
python读取TXT每行,并存到LIST中的方法
Oct 26 Python
python实现n个数中选出m个数的方法
Nov 13 Python
Python中将两个或多个list合成一个list的方法小结
May 12 Python
python scrapy重复执行实现代码详解
Dec 28 Python
基于Python3.7.1无法导入Numpy的解决方式
Mar 09 Python
如何用python反转图片,视频
Apr 24 Python
python多线程方法详解
Jan 18 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、mysqli)访问mysql
2013/02/06 PHP
PHP的Yii框架中移除组件所绑定的行为的方法
2016/03/18 PHP
php使用SAE原生Mail类实现各种类型邮件发送的方法
2016/10/10 PHP
火狐浏览器(firefox)下获得Event对象以及keyCode
2008/11/13 Javascript
Javascript valueOf 使用方法
2008/12/28 Javascript
JQuery中getJSON的使用方法
2010/12/13 Javascript
Chrome Form多次提交表单问题的解决方法
2011/05/09 Javascript
JavaScript实现简单获取当前网页网址的方法
2015/11/09 Javascript
简单谈谈json跨域
2016/03/13 Javascript
jQuery版AJAX简易封装代码
2016/09/14 Javascript
jQuery模拟爆炸倒计时功能实例代码
2017/08/21 jQuery
Vue render深入开发讲解
2018/04/13 Javascript
Vue中用props给data赋初始值遇到的问题解决
2018/11/27 Javascript
Koa 中的错误处理解析
2019/04/09 Javascript
vue实现一拉到底的滑动验证
2019/07/25 Javascript
vue中使用[provide/inject]实现页面reload的方法
2019/09/30 Javascript
Python利用pandas计算多个CSV文件数据值的实例
2018/04/19 Python
Python常见MongoDB数据库操作实例总结
2018/07/24 Python
python生成1行四列全2矩阵的方法
2018/08/04 Python
python:接口间数据传递与调用方法
2018/12/17 Python
python Canny边缘检测算法的实现
2020/04/24 Python
Python生成pdf目录书签的实例方法
2020/10/29 Python
德国知名健康零食网上商店:Seeberger
2017/07/27 全球购物
澳大利亚拥有最佳跳伞降落点和最好服务的跳伞项目运营商:Skydive Australia
2018/03/05 全球购物
如何实现jdbc性能优化
2012/07/30 面试题
什么是事务?事务有哪些性质?
2012/03/11 面试题
小区门卫岗位职责
2013/12/31 职场文书
集体婚礼证婚词
2014/01/13 职场文书
音乐器材管理制度
2014/01/31 职场文书
评析教师个人的自我评价
2014/02/19 职场文书
一体化教学实施方案
2014/05/10 职场文书
党员教师四风问题对照检查材料
2014/09/26 职场文书
毕业设计指导教师评语
2014/12/30 职场文书
在校大学生才艺比赛策划书怎么写?
2019/08/26 职场文书
Golang 编译成DLL文件的操作
2021/05/06 Golang
「月刊Comic Alive」2022年5月号封面公开
2022/03/21 日漫