首页 > 编程笔记 > Python笔记

Python迭代器与可迭代对象的区别与联系

迭代,是重复反馈过程的活动,通常是为了逼近所需目标或结果。每对过程重复一次称为一次“迭代”,而每次迭代得到的结果会作为下一次迭代的初始值。在 Python 中,迭代是访问集合型数据的一种方式,对于字符串、列表、元组、集合和字典,都可以使用迭代来遍历其中的每个元素,而这些可以使用 for 循环遍历的对象也被称为可迭代对象。

迭代器是将一个可迭代对象添加了迭代遍历特性后变换而成的对象。迭代器有以下特点:
可迭代对象不一定是迭代器,但迭代器一定是可迭代对象,二者的关系可以用图 1 表示。

可迭代对象与迭代器的关系
图 1:可迭代对象与迭代器的关系

可以使用 isinstance( ) 函数检查一个对象是迭代器还是可迭代对象,例如:

from collections import Iterable, Iterator
isinstance('abc', Iterable)
isinstance([1,2,3], Iterable)
isinstance((1,2), Iterable)
isinstance({1, 2}, Iterable)
isinstance(123, Iterable)

isinstance('abc', Iterator)
isinstance([1,2,3], Iterator)
isinstance((1,2), Iterator)
isinstance({1,2}, Iterator)
isinstance(123, Iterator)

上述代码的运行结果如下所示:

>>> from collections import Iterable, Iterator
>>> isinstance('abc', Iterable)
True
>>> isinstance([1,2,3], Iterable)
True
>>> isinstance((1,2), Iterable)
True
>>> isinstance({1, 2}, Iterable)
True
>>> isinstance(123, Iterable)
False
>>> isinstance('abc', Iterator)
False
>>> isinstance([1,2,3], Iterator)
False
>>> isinstance((1,2), Iterator)
False
>>> isinstance({1,2}, Iterator)
False
>>> isinstance(123, Iterator)
False

可见,字符串、列表、元组、字典都是可迭代对象,普通数字不是可迭代对象;这些数据类型的对象都不直接是迭代器。

区分迭代器和可迭代对象的原则是:
迭代对象本身不一定是迭代器,但可以通过其 __iter__() 方法得到对应的迭代器对象。定义可迭代对象,必须实现 __iter__() 方法;定义迭代器,必须实现 __iter__() 和 __next__() 方法。

对于可迭代对象,可以使用 iter( ) 函数得到其对应的迭代器对象,使用 next( ) 函数获取该迭代器对象当前返回的元素,例如:
l = [1, 2, 3]
iterName=iter(l)
print(iterName)
print(next(iterName))
print(next(iterName))
print(next(iterName))
print(next(iterName))
上述代码的运行结果如下所示:

>>> l = [1, 2, 3]
>>> iterName=iter(l)
>>> print(iterName)
<list_iterator object at 0x0000017D355F8D00>
>>> print(next(iterName))
1
>>> print(next(iterName))
2
>>> print(next(iterName))
3
>>> print(next(iterName))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
    print(next(iterName))
StopIteration


可见,iter( ) 函数与 __iter__() 方法联系非常紧密,iter()是直接调用该对象的 __iter__() 方法,并将其返回结果作为自己的返回值,next( ) 函数则是调用该对象的 __next__() 方法获取当前元素。上例中在得到列表l最后一个元素3后再一次使用了 next( )  函数,而此时列表l中已经没有可获取的元素了,所以抛出了异常。

因此,通俗地说,可以将迭代器简单理解为“内置了 for 循环的可迭代对象”,每使用 next( ) 函数访问一次迭代器对象,其在返回当前元素的同时,内部指针将指向下一个元素。

所有教程

优秀文章