【Python】解析Python中的迭代器
目录结构:
在开始文章之前,先贴上一张Iterable、Iterator与Generator之间的关系图:
1. Iterator VS Iterable
迭代器(Iterator)
迭代器是实现了迭代器协议的类对象,迭代器协议规定了迭代器类必需定义__next()__方法。当对迭代器对象调用next()方法时,对象会去调用__next()__计算迭代器的返回值。
可迭代对象(Iterable)
可迭代对象可以是任何对象,不一定是能返回迭代器的数据结构。一个可迭代对象会直接或间接性的调用这两个方法__iter()__和__next()__;其中__iter()__方法只能返回迭代器对象,__next()__则供给迭代器进行调用。
通常情况下,可迭代类都会实现__iter()__和__next()__,并且__iter()__返回它自己,换句话说,该类即是迭代器又是可迭代类。
下面的代码展示了迭代器和可迭代器对象之间的差别:
a_set = {1, 2, 3}#定义set数据类型,set是可迭代类型
b_iterator = iter(a_set)#得到set的迭代器
#Output: 1
print(next(b_iterator))
#Output: <class 'set'>
print(type(a_set))
#Output: <class 'set_iterator'>
print(type(b_iterator))
从结果可以看出a_set是一个可迭代类型(set类型),b_iterator是一个迭代器(set_iterator),它们两个是完全不一同的类型。
下面的自定义了一个迭代器:
class Series(object):
def __init__(self, low, high):
self.current = low
self.high = high def __iter__(self):
return self def __next__(self):
if self.current > self.high:
raise StopIteration
else:
self.current += 1
return self.current - 1 n_list = Series(1,10)
print(list(n_list))
从上面的代码可以看出,__iter__返回了迭代器本身。__next__返回迭代器的下一个值,如果没有下一个返回值那么会抛出StopIteration异常。如果没有在合适的位置抛出StopIteration异常结束迭代,那么在某些循环语句中(例如:for loop),将会形成死循环,所以在__next__中必需要在合适位置添加退出语句(抛出StopIterator异常)。
2.Itertools 模块
Itertools是Python的内置模块,其中包含了能够创建迭代器的函数。简而言之,它提供了许多能够与迭代器交互的方法。
下面是我们使用Itertools模块中count函数的案例:
from itertools import count
sequence = count(start=0, step=1)
while(next(sequence) <= 10):
print(next(sequence),end=" ")
输出:
1 3 5 7 9 11
Itertools中的cycle函数可以创建无限迭代器,例如:
from itertools import cycle
dessert = cycle(['Icecream','Cake'])
count = 0
while(count != 4):
print('Q. What do we have for dessert? A: ' + next(dessert))
count+=1
输出:
Q. What do we have for dessert? A: Icecream
Q. What do we have for dessert? A: Cake
Q. What do we have for dessert? A: Icecream
Q. What do we have for dessert? A: Cake
关于更多itertools模块的使用,可以参见python文档。
3.生成器(Generator)
生成器可以说是迭代器的亲兄弟,生成器允许我们像上面那样写迭代器而不用额外定义__iter__()和__next__()方法。
看下面的案例:
def series_generator(low, high):
while low <= high:
yield low
low += 1 n_list = []
for num in series_generator(1,10):
n_list.append(num) print(n_list)
如果一个方法中出现了yield关键字,那么该方法就是一个生成器。生成器中没有return语句,函数的返回值实际上是一个generator。当循环开始执行到yield语句后,low的值会被扩展到要返回的generator中。当下一次循环再次到达yield语句时,generator会从上一次停止的地方恢复执行,并且将最新的low值添加到generator中。这样一种循环,直到low>high退出循环。
生成器支持延迟计算,只有当去取生成器中的值时才会执行生成器的函数体。
例如:
def test():
print("进入test函数")
for i in range(2):
print("yield number ",i)
yield i
if "__main__" == __name__:
print("开始调用test")
res = test()
print("结束调用test")
next(res)
next(res)
输出:
开始调用test
结束调用test
第一次next(res)
进入test函数
yield number 0
第二次next(res)
yield number 1
从结果可以看出,只有使用next调用迭代器时(使用for,while循环也可以),才会去执行生成器函数中的内容。
python中生成器可以分为生成器函数和生成器表达式,这两种类型的表现形式完全不同。
生成器函数是一个函数体中有yield关键字的,我们上面定义的test就是生成器函数。
生成器表达式的使用比较受限制,一个生成器表达式返回一个生成器。下面是一个使用生成器表达式的案例:
squares = (x * x for x in range(1,10))
print(type(squares))
print(list(squares))
输出:
<class 'generator'>
[1, 4, 9, 16, 25, 36, 49, 64, 81]
生成器的效率是非常高的,生成器可以更好的利用内存和CPU的使用效率,并且通常生成器的代码都比较少,这使用生成器的代码非常好容易理解。应此应该尽量多的在代码中使用生成器
参考文档
https://www.datacamp.com/community/tutorials/python-iterator-tutorial
【Python】解析Python中的迭代器的更多相关文章
- 用python解析pdf中的文本与表格【pdfplumber的安装与使用】
我们接触到的很多文档资料都是以pdf格式存在的,比如:论文,技术文档,标准文件,书籍等.pdf格式使得用机器从中提取信息格外困难. 为了解决这个问题,我找到了几种解决方案,最后选择了python上的p ...
- Python解析CSV中的多维字典
CSV文件结构如下,其中字段A为唯一 代码如下,Python27 with open(file_obj+'TEST.CSV','r') as f: #转为字典 Reader=csv.DictReade ...
- python解析excel中图片+提取图片
解析表格是常用的技术.但是有些表各里面有图片怎么办?我想获得表格里面的图片,值得注意的是,图片没有位置信息,所以最好给图片进行编号,编号代表位置. 下面附上提取表格里面图片的代码.只要输出表格地址,和 ...
- python解析网页中js动态添加的内容
https://www.cnblogs.com/asmblog/archive/2013/05/07/3063809.html https://www.zhihu.com/question/21471 ...
- 从json到python解析python,从bson到monogdb
1.JSON JSON是JavaScript Object Notation的缩写,中文译为JavaScript对象表示法.用来作为数据交换的文本格式,作用类似于XML,而2001年Douglas C ...
- python is、==区别;with;gil;python中tuple和list的区别;Python 中的迭代器、生成器、装饰器
1. is 比较的是两个实例对象是不是完全相同,它们是不是同一个对象,占用的内存地址是否相同 == 比较的是两个对象的内容是否相等 2. with语句时用于对try except finally 的优 ...
- Python使用设计模式中的责任链模式与迭代器模式的示例
Python使用设计模式中的责任链模式与迭代器模式的示例 这篇文章主要介绍了Python使用设计模式中的责任链模式与迭代器模式的示例,责任链模式与迭代器模式都可以被看作为行为型的设计模式,需要的朋友可 ...
- 解析Python编程中的包结构
解析Python编程中的包结构 假设你想设计一个模块集(也就是一个"包")来统一处理声音文件和声音数据.通常由它们的扩展有不同的声音格式,例如:WAV,AIFF,AU),所以你可能 ...
- python中的迭代器详解
#原创,转载请先联系 理论性的东西有点枯燥,耐心点看- 1.迭代是什么? 我们知道可以对list,tuple,dict,str等数据类型使用for...in的循环语法,从其中依次取出数据,这个过程叫做 ...
- Python可迭代对象、迭代器和生成器
Python可迭代对象.迭代器和生成器 python 函数 表达式 序列 count utf-8 云栖征文 python可迭代对象 python迭代器 python生成器 摘要: 8.1 可迭代对象( ...
随机推荐
- easyui datagrid Column Group 列组、 复杂表头 嵌套表头 组合表头 (转载)
核心: rowspan:2 //占两行 colspan:3 //占三列 所有的colspan下的二级列表头,统一放在一个数组里. 文章一: 转载来源:https://blog.csdn.ne ...
- mybatis批量新增报错 BadSqlGrammarException
org.springframework.jdbc.BadSqlGrammarException: ### Error updating database. Cause: com.mysql.jdbc. ...
- linux中网络部分的总结
二.简述iproute家族命令 静态配置地址的方法有一下几种方式: (1)ifconfig (2)ip命令 (3)GUI工具 (4)TUI工具 (5)编辑配置文件 1.ifconfig 查看接口:if ...
- python3在win10运行CGI
痛苦是保持清醒最好的方式 --秦时明月·奶盖 CGI是什么 CGI是目前由NCSA维护,NCSA定义CGI如下: CGI(Common Gateway interface),通用网关接口,它是一段 ...
- php调停者模式(mediator pattern)
差不多了,睡一觉,下次再弄. <?php /* The more classes we have in our software, the more complex their communic ...
- Palisection(Codeforces Beta Round #17E+回文树)
题目链接 传送门 题意 给你一个串串,问你有多少对回文串相交. 思路 由于正着做不太好算答案,那么我们考虑用总的回文对数减去不相交的回文对数. 而不相交的回文对数可以通过计算以\(i\)为右端点的回文 ...
- GoogleUpdate计划任务提权
1.默认低权限无法写入: 2.配置低权限可操控:icacls Update /grant everyone:f 3.下载可执行程序:certutil -urlcache -split -f http: ...
- linux查看反汇编
生成反汇编文件 gcc xxx.c -g -o a.out objdump a.out -dSsx > file 调试的时候查看反汇编: gdb a.out ...layout asm 参考博文 ...
- [转]Reids配置文件redis.conf中文详解
转自: Reids配置文件redis.conf中文详解 redis的各种配置都是在redis.conf文件中进行配置的. 有关其每项配置的中文详细解释如下: 对应的中文版解释redis.conf # ...
- [CQOI2007]涂色paint(BZOJ 1260)题解
题目描述 假设你有一条长度为5的木版,初始时没有涂过任何颜色.你希望把它的5个单位长度分别涂上红.绿.蓝.绿.红色,用一个长度为5的字符串表示这个目标:RGBGR. 每次你可以把一段连续的木版涂成一个 ...