1.为何要有迭代器?
对于序列类型:字符串、列表、元组,我们可以使用索引的方式迭代取出其包含的元素。但对于字典、集合、文件等类型是没有索引的,若还想取出其内部包含的元素,则必须找出一种不依赖于索引的迭代方式,这就是迭代器。
2.什么是迭代器协议、可迭代对象、迭代器?
迭代器协议:
迭代器协议是指:对象必须提供一个next
方法,执行该方法要么返回迭代的下一项,要么就引起一个 StopIteration
异常,以终止迭代(只能往后走 不能往前推)。
可迭代对象:
实现了迭代器协议的对象称为可迭代对象Iterable。
实现方法:对象内部定义__iter__()
方法
迭代器:
可迭代对象执行了obj.__iter__()
后得到的结果就是迭代器,迭代器是即内置有__iter__
又内置有__next__
方法的对象。
3.Python中的for循环
3.1 for循环本质
由于字符串、列表、元组、字典、集合、文件等这些对象都不是迭代器,而在for
循环内部,调用了这些对象的__iter__()
方法,从而将这些对象变成了迭代器,然后调用迭代器的__next__
方法进行取值,并且for
循环最后会捕捉 StopIteration
异常,以终止迭代。
3.2 for循环工作原理
l = [1, 2, 3, 4, 5]
for i in l:
print(i)
以上这个for
循环其内部执行了如下操作:
- 执行
l.__iter__()
方法,得到一个迭代器对象iter_l
; - 执行
iter_l.__next__()
,将得到的值赋值给i
,然后执行循环体代码; - 重复过程2,直到捕捉到异常
StopIteration
,结束循环;
3.3 模拟for循环
# 模拟for循环
l = [1, 2, 3, 4, 5]
# 1.执行l.__iter__()方法,得到一个迭代器对象iter_l
iter_l = l.__iter__()
while True:
try:
# 2.执行iter_l.__next__(),将得到的值赋值给i,然后执行循环体代码;
i = iter_l.__next__()
print(i)
# 3.直到捕捉到异常StopIteration,结束循环
except StopIteration:
break
4.迭代器的优缺点
优点:
- 提供一种统一的、不依赖于索引的迭代方式
- 惰性计算,节省内存
缺点
- 无法获取长度(只有在next完毕才知道到底有几个值)
- 一次性的,只能往后走,不能往前退
(完)