迭代器与生成器
迭代是 Python 的核心机制,for 循环、列表推导、生成器表达式都建立在迭代协议之上。
可迭代对象与迭代器
可迭代对象(Iterable):实现 __iter__(),返回迭代器。
迭代器(Iterator):实现 __iter__() 和 __next__(),__next__() 结束时抛出 StopIteration。
1 2 3 4 5 6
| nums = [1, 2, 3] it = iter(nums) next(it) next(it) next(it) next(it)
|
内置可迭代:list、tuple、dict、set、str、文件对象等。
自定义迭代器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| class CountDown: def __init__(self, start: int): self.current = start
def __iter__(self): return self
def __next__(self) -> int: if self.current <= 0: raise StopIteration self.current -= 1 return self.current + 1
for n in CountDown(3): print(n)
|
生成器函数
用 yield 简化迭代器实现:
1 2 3 4 5 6 7 8 9 10 11
| def countdown(start: int): while start > 0: yield start start -= 1
for n in countdown(3): print(n)
gen = countdown(3) next(gen) next(gen)
|
生成器是惰性的:按需产生值,节省内存。
生成器表达式
1 2
| squares = (x ** 2 for x in range(1000000)) total = sum(x ** 2 for x in range(100))
|
与列表推导 [...] 的区别:生成器表达式用 (),返回生成器而非列表。
yield from
委托子生成器:
1 2 3 4 5
| def chain(*iterables): for it in iterables: yield from it
list(chain([1, 2], [3, 4]))
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| import itertools
itertools.count(10, 2) itertools.cycle("AB") itertools.repeat(7, 3)
itertools.chain([1, 2], [3, 4]) itertools.islice(range(100), 5, 10) itertools.product([1, 2], ["a", "b"]) itertools.permutations([1, 2, 3], 2) itertools.combinations([1, 2, 3], 2)
for key, group in itertools.groupby("aaabbccc"): print(key, list(group))
|
应用场景
大文件处理
1 2 3 4
| def read_large_file(path: str): with open(path, encoding="utf-8") as f: for line in f: yield line.strip()
|
管道式数据处理
1 2 3 4 5 6 7 8 9 10 11 12
| def parse_lines(lines): for line in lines: yield line.split(",")
def filter_empty(records): for rec in records: if rec: yield rec
pipeline = filter_empty(parse_lines(read_large_file("data.csv"))) for row in pipeline: process(row)
|
小结
- 迭代协议:
__iter__ + __next__
- 生成器用
yield,惰性求值,适合大数据流
itertools 提供丰富的迭代工具
- 列表推导求值全部元素,生成器表达式按需求值