可迭代对象通过iter(),转化为迭代器对象,迭代器可以使用next()访问,可迭代对象不能直接使用next();
- 迭代器是一个可以记住遍历的位置的对象,所以可以方便的使用next()。
可迭代对象(iterable):凡是具有__iter__的方法的类,都是可迭代的类。可迭代类创建的对象实现了__iter__方法,因此就是可迭代对象。用list、tuple等容器创建的对象,都是可迭代对象。下面两个例子:
Eg1:
my_list = [1, 2, 3]
for item in my_list: # 可迭代对象
print(item) # 输出:1 2 3
Eg2
for i, item in enumerate([1, 2, 3]): # 迭代器对象
print(f'index: {i}, item: {item}')
-
enumerate()
是一个内置函数,它可以同时遍历一个列表的索引和元素。这个函数接受一个可迭代对象作为参数,并返回一个迭代器,该迭代器每次返回一对(索引,元素)。
这里就产生了一个疑问?为什么Eg1 for遍历的是一个iterable,Eg2 for遍历的是一个iterator?
解答:for循环的工作机制:
- 当对象本身就是迭代器时,For循环工作机制;
- 调用 __iter__方法,返回自身self,也就是返回迭代器;
- 不断地调用迭代器的next()方法,每次按序返回迭代器中的一个值;
- 迭代到最后没有元素时,就抛出异常 StopIteration,这个异常 python 自己会处理,不会暴露给开发者;
- 在可迭代对象中,for循环工作机制;
- 先判断对象是否为可迭代对象(等价于判断有没有__iter__或__getitem__方法),没有的话直接报错,抛出TypeError异常。有的话,调用 __iter__方法,返回一个迭代器。
- 在python内部不断地调用迭代器的__next__方法,每次按序返回迭代器中的一个值;
- 迭代到最后没有元素时,就抛出异常 StopIteration,这个异常 python 自己会处理,不会暴露给开发者。
总结:
For循环深层还是对迭代器进行遍历,只不过会自动的可迭代对象转换为迭代器。
参考目录: