[TOC]
一 迭代器介绍
迭代器即用来迭代取值的工具, 而迭代是重复反馈过程的活动, 其目的通常是为了逼近所需的目标或结果, 每一次对过程的重复称为一次 "迭代", 而每一次迭代得到的结果会作为下一次迭代的初始值, 单纯的重复并不是迭代
- while True:
- msg = input('>>:').strip()
- print(msg)
下述 while 循环才是一个迭代过程, 不仅满足重复, 而且以每次重新赋值后的 index 值作为下一次循环中新的索引进行取值, 反复迭代, 最终可以取尽列表中的值
- goods=['mac','lenovo','acer','dell','sony']
- index=0
- while index <len(goods):
- print(goods[index])
- index+=1
插图: 恶搞图 43
1.1 可迭代对象
通过索引的方式进行迭代取值, 实现简单, 但仅适用于序列类型: 字符串, 列表, 元组. 对于没有索引的字典, 集合等非序列类型, 必须找到一种不依赖索引来进行迭代取值的方式, 这就用到了迭代器.
要想了解迭代器为何物, 必须事先搞清楚一个很重要的概念: 可迭代对象(Iterable). 从语法形式上讲, 内置有__iter__方法的对象都是可迭代对象, 字符串, 列表, 元组, 字典, 集合, 打开的文件都是可迭代对象:
- {
- 'name':'egon'
- }.__iter__
- {
- 7,8,9
- }.__iter__
- ......
插图: 恶搞图 44
1.2 迭代器对象
调用 obj.iter()方法返回的结果就是一个迭代器对象 (Iterator). 迭代器对象是内置有 iter 和 next 方法的对象, 打开的文件本身就是一个迭代器对象, 执行迭代器对象. iter() 方法得到的仍然是迭代器本身, 而执行迭代器. next()方法就会计算出迭代器中的下一个值. 迭代器是 Python 提供的一种统一的, 不依赖于索引的迭代取值方式, 只要存在多个 "值", 无论序列类型还是非序列类型都可以按照迭代器的方式取值
- >>> s={
- 1,2,3
- } # 可迭代对象 s
- >>> i=iter(s) # 本质就是在调用 s.__iter__(), 返回 s 的迭代器对象 i,
- >>> next(i) # 本质就是在调用 i.__next__()
- 1
- >>> next(i)
- 2
- >>> next(i)
- 3
- >>> next(i) #抛出 StopIteration 的异常, 代表无值可取, 迭代结束
插图: 恶搞图 45
二 for 循环原理
有了迭代器后, 我们便可以不依赖索引迭代取值了, 使用 while 循环的实现方式如下
- goods=['mac','lenovo','acer','dell','sony']
- i=iter(goods) #每次都需要重新获取一个迭代器对象
- while True:
- try:
- print(next(i))
- except StopIteration: #捕捉异常终止循环
- break
for 循环又称为迭代循环, in 后可以跟任意可迭代对象, 上述 while 循环可以简写为
- goods=['mac','lenovo','acer','dell','sony']
- for item in goods:
- print(item)
for 循环在工作时, 首先会调用可迭代对象 goods 内置的 iter 方法拿到一个迭代器对象, 然后再调用该迭代器对象的 next 方法将取到的值赋给 item, 执行循环体完成一次循环, 周而复始, 直到捕捉 StopIteration 异常, 结束迭代.
插图: 恶搞图 48
三 迭代器的优缺点
基于索引的迭代取值, 所有迭代的状态都保存在了索引中, 而基于迭代器实现迭代的方式不再需要索引, 所有迭代的状态就保存在迭代器中, 然而这种处理方式优点与缺点并存:
3.1 优点:
1, 为序列和非序列类型提供了一种统一的迭代取值方式.
2, 惰性计算: 迭代器对象表示的是一个数据流, 可以只在需要时才去调用 next 来计算出一个值, 就迭代器本身来说, 同一时刻在内存中只有一个值, 因而可以存放无限大的数据流, 而对于其他容器类型, 如列表, 需要把所有的元素都存放于内存中, 受内存大小的限制, 可以存放的值的个数是有限的.
插图: 恶搞图 46
3.2 缺点:
1, 除非取尽, 否则无法获取迭代器的长度
2, 只能取下一个值, 不能回到开始, 更像是'一次性的', 迭代器产生后的唯一目标就是重复执行 next 方法直到值取尽, 否则就会停留在某个位置, 等待下一次调用 next; 若是要再次迭代同个对象, 你只能重新调用 iter 方法去创建一个新的迭代器对象, 如果有两个或者多个循环使用同一个迭代器, 必然只会有一个循环能取到值.
插图: 恶搞图 47
来源: http://www.bubuko.com/infodetail-3350009.html