可迭代对象和迭代器
可迭代对象 (Iterable) 是指那些能够逐一返回其内部成员的对象(返回迭代器)。换句话说,任何你可以用 for 循环进行遍历的对象,都是可迭代对象。
常见的可迭代对象
常见的可迭代对象包括:
- 序列 (Sequence):如列表 (list)、元组 (tuple)、字符串 (str)。
- 集合 (Set):如 set、frozenset。
- 映射 (Mapping):如字典 (dict)。
- 文件对象。
- 通过 yield 关键字创建的生成器 (Generator)。
1 | # 列表是可迭代的 |
如何判断一个对象是可迭代对象
你可以使用 collections.abc.Iterable
和isinstance来检查一个对象是否是可迭代的:
1 | from collections.abc import Iterable |
迭代器协议 (Iterator Protocol)
一个对象之所以“可迭代”,是因为它遵守了 Python 的迭代器协议。这个协议规定了对象如何支持迭代。我们可以从两个角度来理解这个协议:
- 可迭代对象 (Iterable)
- 定义:一个对象如果实现了 iter() 方法,那么它就是可迭代对象。
- 作用:iter() 方法的职责是返回一个迭代器 (Iterator) 对象。
- List、Tuple、String、Dict、Set 等内置类型都实现了 iter() 方法,因此它们都是可迭代对象。
- 迭代器 (Iterator)
- 定义:一个对象如果同时实现了 iter() 和 next() 方法,那么它就是迭代器。
- iter() 的作用:对于迭代器本身,其 iter() 方法通常只是返回它自己 (self)。
- next() 的作用:这是迭代器的核心。每次调用该方法时,它会返回序列中的下一个元素。当所有元素都返回完毕后,再次调用 next() 会抛出 StopIteration 异常,以告知外部调用者迭代已经结束。
- Generator 对象就是一种特殊的迭代器,它们是通过生成器函数创建的。
需要注意的是, List、Tuple、String、Dict、Set等内置类型不是迭代器,因为它们没有实现 next() 方法, 也就意味着他们不能通过next()逐个访问下一元素(因为他们本身就是有限的集合, 没有必要逐个生成逐个next()访问).
可以使用isinstance()判断一个对象是否是Iterator对象:
1 | from collections.abc import Iterator |
for 循环的幕后工作原理
当我们使用 for 循环时,Python 解释器在背后实际上执行了以下步骤:
获取迭代器:调用可迭代对象的 iter() 方法来获取一个迭代器。
循环取值:在一个循环中,不断地调用迭代器的 next() 方法来获取下一个元素。
处理异常:当 next() 方法抛出 StopIteration 异常时,for 循环会捕获这个异常并优雅地结束循环。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15my_list = [10, 20, 30]
# 1. 获取迭代器
# 这相当于调用了 my_list.__iter__()
my_iterator = iter(my_list)
# 2. 循环取值和处理异常
while True:
try:
# 相当于调用了 my_iterator.__next__()
item = next(my_iterator)
print(item)
except StopIteration:
# 3. 迭代结束,跳出循环
break