Python中的迭代器模式与集合遍历的内部机制
字数 1034 2025-11-24 23:17:53
Python中的迭代器模式与集合遍历的内部机制
1. 问题描述
在Python中,我们经常使用for循环遍历列表、字典等集合对象。这种遍历的背后是迭代器模式的实现。面试题可能涉及:
- 迭代器协议包含哪些方法?
for循环底层如何工作?- 迭代器与可迭代对象的区别是什么?
- 如何自定义一个支持迭代的类?
2. 核心概念:可迭代对象 vs. 迭代器
(1)可迭代对象(Iterable)
- 定义:实现了
__iter__()方法的对象,该方法返回一个迭代器。 - 常见例子:列表、元组、字典、字符串。
- 验证方法:
from collections.abc import Iterable print(isinstance([1, 2], Iterable)) # True
(2)迭代器(Iterator)
- 定义:实现了
__iter__()(返回自身)和__next__()方法的对象。 - 核心行为:
__next__()每次返回一个元素,耗尽时抛出StopIteration异常。- 迭代器是一次性的,遍历完成后需重新创建才能再次遍历。
- 验证方法:
from collections.abc import Iterator print(isinstance(iter([1, 2]), Iterator)) # True
3. for循环的底层机制
以下代码:
for item in [1, 2, 3]:
print(item)
等价于:
# 1. 获取迭代器
iterator = iter([1, 2, 3])
# 2. 循环调用 next()
while True:
try:
item = next(iterator)
print(item)
except StopIteration:
break
步骤解析:
- 调用可迭代对象的
__iter__()方法生成迭代器。 - 反复调用迭代器的
__next__()方法获取元素。 - 捕获
StopIteration异常,退出循环。
4. 自定义迭代器示例
(1)自定义可迭代对象
class MyRange:
def __init__(self, start, end):
self.start = start
self.end = end
def __iter__(self):
# 返回一个迭代器实例
return MyRangeIterator(self.start, self.end)
(2)自定义迭代器
class MyRangeIterator:
def __init__(self, start, end):
self.current = start
self.end = end
def __iter__(self):
return self # 迭代器必须返回自身
def __next__(self):
if self.current >= self.end:
raise StopIteration
value = self.current
self.current += 1
return value
(3)使用简化写法(合并可迭代对象和迭代器)
class MyRange:
def __init__(self, start, end):
self.current = start
self.end = end
def __iter__(self):
return self # 自身就是迭代器
def __next__(self):
if self.current >= self.end:
raise StopIteration
value = self.current
self.current += 1
return value
注意:这种写法会导致迭代器一次性耗尽,无法重复遍历。
5. 迭代器的优势与限制
优势:
- 惰性计算:需要时才生成数据,节省内存(如
range(10**6)不会立即生成100万个数)。 - 统一接口:所有集合类型均可通过同一方式遍历。
限制:
- 单向性:只能向前,不能回退或重置。
- 一次性使用:遍历完成后需重新创建迭代器。
6. 实际应用:生成器作为迭代器的语法糖
生成器(Generator)是更简洁的迭代器实现方式,使用yield关键字:
def my_range(start, end):
current = start
while current < end:
yield current
current += 1
- 生成器函数返回一个生成器对象,自动实现
__iter__()和__next__()。 - 每次执行到
yield时暂停,下次调用next()时恢复状态。
总结
- 可迭代对象:实现
__iter__(),用于生成迭代器。 - 迭代器:实现
__next__()和__iter__(),负责遍历逻辑。 for循环:通过迭代器协议实现,隐藏了StopIteration处理细节。- 生成器是迭代器的便捷实现,适合惰性数据流场景。