在 Python 中,迭代器(Iterator) 和 生成器(Generator) 是非常重要的概念。
它们不仅让代码更优雅,还能显著降低内存占用,是理解 Python “惰性计算”思想的关键。
本文将从以下几个方面展开:
可迭代对象:
只要能被
for循环遍历的对象,就是可迭代对象。
常见的可迭代对象:
判断方式:
from collections.abc import Iterable
isinstance([1, 2, 3], Iterable) # True
注意:
可迭代对象 ≠ 迭代器
迭代器是一个对象,它同时满足两个条件:
__iter__() 方法__next__() 方法判断方式:
from collections.abc import Iterator
isinstance(iter([1, 2, 3]), Iterator) # True
lst = [1, 2, 3]
it = iter(lst)
print(next(it)) # 1
print(next(it)) # 2
print(next(it)) # 3
print(next(it)) # StopIteration
核心机制:
iter() 创建迭代器next() 获取下一个值StopIterationclass Counter:
def __init__(self, limit):
self.limit = limit
self.current = 0
def __iter__(self):
return self
def __next__(self):
if self.current >= self.limit:
raise StopIteration
self.current += 1
return self.current
使用方式:
for i in Counter(3):
print(i)
输出:
1
2
3
生成器是 创建迭代器的更优雅方式。
一句话总结:
生成器 = 语法简化的迭代器
只要函数中出现 yield,它就变成了生成器函数。
def count_up(limit):
current = 0
while current < limit:
current += 1
yield current
使用:
for i in count_up(3):
print(i)
特点:
yield 会暂停函数执行gen = (x * x for x in range(5))
对比列表推导式:
lst = [x * x for x in range(5)] # 立即计算
gen = (x * x for x in range(5)] # 惰性计算
生成器的最大优势:按需计算。
def read_big_file(path):
with open(path) as f:
for line in f:
yield line
优点:
| 对比项 | 迭代器 | 生成器 |
|---|---|---|
| 写法 | 手动实现 | yield |
| 可读性 | 一般 | 很好 |
| 代码量 | 多 | 少 |
| 本质 | 类 | 函数 |
| 推荐 | ❌ | ✅ |
结论:
除非必要,不要手写迭代器。
gen = (i for i in range(3))
list(gen) # [0, 1, 2]
list(gen) # []
原因:生成器是消耗型的。
def gen():
print("start")
yield 1
print("end")
执行顺序由 next() 决定,不直观。
len(gen) # 错误
gen[0] # 错误
def fibonacci():
a, b = 0, 1
while True:
yield b
a, b = b, a + b
使用:
fib = fibonacci()
for _ in range(10):
print(next(fib))
一句话记忆:
能用生成器,就不要手写迭代器。