【Python那些事儿】Python中的迭代器
来源:互联网 发布:算法的乐趣 pdf 编辑:程序博客网 时间:2024/05/17 22:18
迭代器(iterator)协议
- 对象必须提供一个next()方法,执行该方法时,要么返回迭代中的下一项,要么引起一个StopIteration异常。
- 只能往前访问,不会后退。
- 在Python中,支持迭代器协议就是实现对象的
__iter__
和__next__()
方法。__iter__()
方法:返回迭代器对象本身;__next__()
方法:返回容器中的下一个元素,在结尾时引发StopIteration异常终止迭代器。
可迭代对象(iterable)
- 实现了迭代器协议的对象,就是可迭代对象。
- 如何实现迭代器协议:对象内部定义了一个
__iter__()
方法。 - 在Python中,list、tuple、dict、set以及生成器对象都是可迭代对象。如果不确定哪个可迭代,可以使用内置函数
iter()
测试。
>>> iter([6,8,10])#返回listterator对象<listiterator object at 0x7f992a891210>>>> iter({'a':1,'b':2})#返回dictionary-keyiterator对象<dictionary-keyiterator object at 0x7f992a880838>>>> iter(666)#不是可迭代对象Traceback (most recent call last): File "<stdin>", line 1, in <module>TypeError: 'int' object is not iterable
- 所有的iterable均可以通过内置函数
iter()
转化为iterator。
迭代器
- 迭代器对象从集合的第一个元素开始访问,直到所有元素被访问完结束,迭代器只能往前不能后退。
- 迭代器有两个基本方法:iter、text方法。
- 内置函数
iter()
、next()
,本质上都是用的对象的__iter__()
、__next__()
的方法。
- 内置函数
迭代器优点
- 对于支持随机访问的数据结构:list、tuple等,迭代器和经典的for循环(索引访问)相比,并无优势,反而失去了索引值。不过可以使用内置函数
enumerate()
找回这个索引值。但对于无法随机访问的数据结构:set()
,迭代器是唯一的访问元素的方式。 - 省内存:迭代器不需要事先准备好整个迭代过程中的所有元素,仅仅在迭代到某个元素时才计算该元素,而在这之前或之后,元素可以不存在或销毁。这也是迭代器的一大优点:适合用于遍历一个巨大的或无限的集合,比如几个G的文件。下面用斐波那契数列为例:
- 代码一直接在
fab(max)
中用print打印会导致函数的可复用性变差,因此fab返回None。其他函数无法获得fab函数返回的数列; - 代码二满足了可复用性的需求,但是占用了内存空间;
- 代码三Fabs类通过
next()
不断返回数列的下一个,内存占用始终为常数。
- 代码一直接在
#代码一:def fab(max): L = [] n, a, b = 0, 0, 1 while n < max: L.append(b) a, b = b, a + b n = n + 1 return L#代码二: def fab(max): n, a, b = 0, 0, 1 while n < max: print b a, b = b, a + b n = n + 1#代码三:class Fab(object): def __init__(self, max): self.max = max self.n, self.a, self.b = 0, 0, 1 def __iter__(self): return self def next(self): if self.n < self.max: r = self.b self.a, self.b = self.b, self.a + self.b self.n = self.n + 1 return r raise StopIteration()
使用迭代器
- 使用内置函数iter(iterable)获取迭代器对象:
>>> iter(range(5))<listiterator object at 0x7f992a8911d0>>>> iter(xrange(5))<rangeiterator object at 0x7f992a892240>
- 使用
next()
方法访问下一个元素:
>>> a.next()0>>> a.next()1>>> a.next()2>>> a.next()3
- 迭代器越界会抛出StopIteration异常:
>>> a.next()4>>> a.next()Traceback (most recent call last): File "<stdin>", line 1, in <module>StopIteration
处理方法:
lst = range(5)it = iter(lst)try: while True: val = it.next() print valexcept StopIteration: pass#输出01234
注意:Python专门为for关键字做了迭代器的语法糖:在for循环中,Python将自动调用内置函数iter()获得迭代器,自动调用next()获取元素,还完成了检查StopIteration异常的工作。
自定义迭代器
下面例子中实现了一个MyRange的类型,这个类型中实现了__iter__()
方法,通过这个方法返回对象本身作为迭代器对象;同时,实现了next()
方法用来获取容器中的下一个元素,当没有可访问元素后,就抛出StopIteration异常。
class MyRange(object): def __init__(self, n): self.idx = 0 self.n = n def __iter__(self): return self def next(self): if self.idx < self.n: val = self.idx self.idx += 1 return val else: raise StopIteration()myRange = MyRange(5)for i in myRange: print i#输出:01234
0 0
- 【Python那些事儿】Python中的迭代器
- 【Python那些事儿】Python中的类型转换
- 【Python那些事儿】Python中的读写文件
- 【Python那些事儿】Python中的生成器
- python那些事儿
- 关于Python时间的那些事儿
- 关于Python时间的那些事儿
- 【Python那些事儿之七】Iterators详解
- python编解码的那些事儿
- 【Python那些事儿】range()和xrange()
- 【Python那些事儿】使用箱线图
- 【Python那些事儿】数据放缩
- 【Python那些事儿】主成分分析PCA
- python中的那些“神器”
- Opencv3.0-python的那些事儿:(三)、Opencv的图像处理中的几何变换
- 【Python那些事儿】Python字符串连接的5种方法
- 【Python那些事儿】用图表分析单变量数据
- 【Python那些事儿】为多变量数据绘制散点图
- btrace使用
- SSL JudgeOnlie 2324——细胞问题
- LintCode44:最小子数组
- Redis集群搭建1
- 新零售袭来,打造极致体验的乐语能否笑傲江湖?
- 【Python那些事儿】Python中的迭代器
- 清理C盘垃圾命令
- 获取接口调用者的包名
- spring mvc入门教程(一)概念介绍
- 反射笔记
- HCDA
- 带你快速玩转canvas(8)非常用API的说明集
- Caffe error Cannot copy param 0 weights from layer, shape mismatch
- 算法——质数处理