一.迭代器
什么是可迭代对象:for循环可以循环的就是可迭代对象
字符串,列表,元祖,字典,集合,range
迭代器:f1文件句炳
# s = 'laonanhai'# print(dir(s)) # __iter__# l1 = [1, 2, 3, 4]# print(dir(l1)) # __iter__# dic = {'1': 'alex', "2": "老男孩"}# print(dir(dic)) # __iter__
什么是可迭代对象:内部含有__iter__方法的对象就叫做可迭代对象可迭代对象就遵循可迭代协议。如何判断 两种方式
print('__iter__' in dir(s))from collections import Iterablel = [1, 2, 3, 4]print(isinstance(l, Iterable)) # Trueprint(type(l))print(isinstance(l,list))
from collections import Iterable l = [1,2,3,4] t = (1,2,3,4) d = {1:2,3:4} s = {1,2,3,4} print(isinstance(l,Iterable))print(isinstance(t,Iterable))print(isinstance(d,Iterable))print(isinstance(s,Iterable))
1.2可迭代协议
我们现在是从结果分析原因,能被for循环的就是“可迭代的”,但是如果正着想,for怎么知道谁是可迭代的呢?
假如我们自己写了一个数据类型,希望这个数据类型里的东西也可以使用for被一个一个的取出来,那我们就必须满足for的要求。这个要求就叫做“协议”。
可以被迭代要满足的要求就叫做可迭代协议。可迭代协议的定义非常简单,就是内部实现了__iter__方法。
接下来我们就来验证一下:
总结一下我们现在所知道的:可以被for循环的都是可迭代的,要想可迭代,内部必须有一个__iter__方法。
接着分析,__iter__方法做了什么事情呢?
可迭代的:内部必须含有一个__iter__方法。
1.3迭代器
什么叫做迭代器?迭代器英文意思是iterator
l = [1,2,3,4]l_iter = l.__iter__() # 将可迭代的转化成迭代器item = l_iter.__next__()print(item)item = l_iter.__next__()print(item)item = l_iter.__next__()print(item)item = l_iter.__next__()print(item)item = l_iter.__next__()print(item)
迭代器遵循迭代器协议:必须拥有__iter__方法和__next__方法。
for循环,能遍历一个可迭代对象,他的内部到底进行了什么?
- 将可迭代对象转化成迭代器。(可迭代对象.__iter__())
- 内部使用__next__方法,一个一个取值。
- 加了异常处理功能,取值到底后自动停止。
用while循环模拟for循环: l = [1,2,3,4]l_iter = l.__iter__()while True: try: item = l_iter.__next__() print(item) except StopIteration: break
1.4为什么要有for循环?
基于上面讲的列表这一大堆遍历方式,聪明的你立马看除了端倪,于是你不知死活大声喊道,你这不逗我玩呢么,有了下标的访问方式,我可以这样遍历一个列表啊
没错,序列类型字符串,列表,元组都有下标,你用上述的方式访问,perfect!但是你可曾想过非序列类型像字典,集合,文件对象的感受,所以嘛,年轻人,for循环就是基于迭代器协议提供了一个统一的可以遍历所有对象的方法,即在遍历之前,先调用对象的__iter__方法将其转换成一个迭代器,然后使用迭代器协议去实现循环访问,这样所有的对象就都可以通过for循环来遍历了,而且你看到的效果也确实如此,这就是无所不能的for循环,最重要的一点,转化成迭代器,在循环时,同一时刻在内存中只出现一条数据,极大限度的节省了内存~