跳至主要內容

迭代器、生成器

pptg大约 2 分钟

1. 迭代器

迭代器实现了迭代器协议,是一个可以记住遍历位置的对象,必须提供两个方法:

  • __iter__(): 返回迭代器对象本身
  • __next__(): 返回下一个值,如果没有了就排除StopIteration异常
自定义迭代器
# 自定义迭代器
class CountDown:
    """倒计时迭代器"""
    
    def __init__(self, start):
        self.current = start
    
    def __iter__(self):
        return self  # 返回迭代器本身
    
    def __next__(self):
        if self.current <= 0:
            raise StopIteration  # 没有更多元素时抛出异常
        value = self.current
        self.current -= 1
        return value

# 使用自定义迭代器
print("=== 自定义迭代器 ===")
countdown = CountDown(5)
for number in countdown:
    print(number)  # 5, 4, 3, 2, 1

# 手动使用迭代器
print("\n=== 手动使用迭代器 ===")
countdown2 = CountDown(3)
print(next(countdown2))  # 3
print(next(countdown2))  # 2
print(next(countdown2))  # 1
# print(next(countdown2))  # 会抛出 StopIteration

2. 生成器

生成器是一种使用yield关键字,更简单创建迭代器的方式

生成器函数
# 生成器函数 - 使用 yield
def countdown_generator(n):
    """倒计时生成器"""
    print("生成器开始")
    while n > 0:
        print(f"准备生成: {n}")
        yield n  # 暂停执行,返回n
        n -= 1
    print("生成器结束")

print("=== 生成器函数 ===")
gen = countdown_generator(3)
print("生成器创建完成,但还没有执行")

# 第一次调用next()
print(next(gen))  # 输出: 准备生成: 3 → 3
print("暂停...")

# 第二次调用next()
print(next(gen))  # 输出: 准备生成: 2 → 2
print("暂停...")

# 第三次调用next()
print(next(gen))  # 输出: 准备生成: 1 → 1
print("暂停...")

# 第四次调用会抛出 StopIteration
# print(next(gen))

3. 两者区别

特性迭代器生成器
创建方式实现__iter__和__next__使用yield或生成器表达式
代码复杂度相对复杂简单
内存使用取决于实现极低,懒加载,只会在需要的时候生成值,然后暂停直到下次请求
状态保持手动维护自动保持
适用场景复杂迭代简单迭代