迭代器、生成器
大约 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
内置迭代器
# 常见的可迭代对象
numbers = [1, 2, 3]
string = "hello"
dictionary = {'a': 1, 'b': 2}
# 获取迭代器
numbers_iter = iter(numbers)
string_iter = iter(string)
dict_iter = iter(dictionary) # 迭代键
print("=== 内置迭代器 ===")
print(next(numbers_iter)) # 1
print(next(string_iter)) # h
print(next(dict_iter)) # a
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))
生成器表达式
# 生成器表达式 - 类似列表推导式,但使用圆括号
print("=== 生成器表达式 ===")
# 列表推导式 - 立即计算所有值
squares_list = [x**2 for x in range(5)]
print(f"列表: {squares_list}") # [0, 1, 4, 9, 16]
# 生成器表达式 - 按需生成值
squares_gen = (x**2 for x in range(5))
print(f"生成器: {squares_gen}") # <generator object <genexpr> at 0x...>
# 使用生成器
print("逐个获取值:")
for square in squares_gen:
print(square) # 0, 1, 4, 9, 16
3. 两者区别
| 特性 | 迭代器 | 生成器 |
|---|---|---|
| 创建方式 | 实现__iter__和__next__ | 使用yield或生成器表达式 |
| 代码复杂度 | 相对复杂 | 简单 |
| 内存使用 | 取决于实现 | 极低,懒加载,只会在需要的时候生成值,然后暂停直到下次请求 |
| 状态保持 | 手动维护 | 自动保持 |
| 适用场景 | 复杂迭代 | 简单迭代 |