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  

步骤解析

  1. 调用可迭代对象的__iter__()方法生成迭代器。
  2. 反复调用迭代器的__next__()方法获取元素。
  3. 捕获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. 迭代器的优势与限制

优势

  1. 惰性计算:需要时才生成数据,节省内存(如range(10**6)不会立即生成100万个数)。
  2. 统一接口:所有集合类型均可通过同一方式遍历。

限制

  1. 单向性:只能向前,不能回退或重置。
  2. 一次性使用:遍历完成后需重新创建迭代器。

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