可迭代对象通过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循环深层还是对迭代器进行遍历,只不过会自动的可迭代对象转换为迭代器。

参考目录:

Python中的可迭代对象、迭代器、For循环工作机制、生成器 – 个人文章 – SegmentFault 思否

Python3 迭代器与生成器 | 菜鸟教程 (runoob.com)