Python生成器generator原理及用法解析
作者:吃着东西不想停 发布时间:2021-10-14 14:00:13
前言
生成器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)
来源:https://www.cnblogs.com/zwhy8/p/13336400.html


猜你喜欢
- 一、使用 PyCharm 软件安装 pandas 包1、打开 PyCharm2、点击右上角 “Files” →“Settings...”3、
- 概括、从python1.6开始就可以处理unicode字符了。 一、几种常见的编码格式。 1.1、ascii,用1个字节表示。 1.2、UT
- js 代码中经常会碰到 undefined 这种错误,下面本文分享一下为什么会发生这种错误以及如何处理这种错误,js 中如果通过 var 声
- TabularInline类用于在A页面上编辑B表的字段,举例说明,如果models.py中有Staff、Job两个model:from d
- 正则表达式gi我刚开始也看不懂,从网上找到后看到了,现在分享给大家正在表达式的通项: /pattern/flags 即(/模式/标记 )构造
- python-docx库可用于创建和编辑Microsoft Word(.docx)文件。官方文档:链接地址备注:doc是微软的专有的文件格式
- 在平时的工作中,我们经常会遇到需要批量创建文件的情况,例如,汇总一个月中每天回复问题的文件等,这里,我们以如何使用当前日期时间创建文件为例:
- < SCRIPT LANGUAGE="VBScript"> < 
- ///计算两个整数的百分比值 function GetPercent(num, total) { num = parseFloat(num)
- MySQL死锁问题是很多程序员在项目开发中常遇到的问题,现就MySQL死锁及解决方法详解如下:1、MySQL常用存储引擎的锁机制MyISAM
- 开发环境:Ubuntu16.04+Django 1.11.9+Python2.7一:使用自定义函数输出日志到log文件:import tim
- 本文实例为大家分享了JS实现拖动模糊框特效的具体代码,供大家参考,具体内容如下需求:在图片上拖动按钮,图片蒙层慢慢覆盖,当蒙层边缘碰到左右下
- 对于任何一个开发项目来说最大的错误可能就是没有计划。最近,有些人认为开始前无需计划,一个优秀的开发者需要的是随机应变。我敢肯定这样的做法最后
- rabbitmq中文翻译的话,主要还是mq字母上:Message Queue,即消息队列的意思。前面还有个rabbit单词,就是兔子的意思,
- 前言今天继续加油学习,今天整理一下VUE中生命周期那有些,平且依次说明给个的使用场景以及作用。嘻嘻嘻,让我们一起学起来好吧生命周期befor
- flask中的sqlalchemy 相比于sqlalchemy封装的更加彻底一些 , 在一些方法上更简单首先import类库:在CODE上查
- 科学设计你的网站网页:来自 Eye-Tracking研究的23节必修课 ——Christina Laun在网络设计领域关于Eye-
- 由于一些原因,视频录制要告一段落了。再写一篇关于cntk的文章分享出来吧。我也很想将这个事情进行下去。以后如果条件允许还会接着做。cntk2
- 官方网站:http://www.extjs.com/演示地址:http://www.yaohaixiao.com/effects/sampl
- 1.max取最大值函数max() 方法返回给定参数的最大值,参数可以为序列。lis = [1,2,3,-4]print(max(lis))