生成器是一个函数,它使用 yield 关键字而不是 return 来缓慢地、一次一个地生成值。它根据需要计算每个值,而不是在内存中构建整个结果——非常适合大型或无限序列。
yield vs return
python
():
[i ** i (n)]
():
i (n):
i **
sq gen_squares():
(sq)
yield 暂停函数,返回一个值,并在下一次迭代时从那个确切的点恢复 ——保留值之间的本地状态。在请求之前不计算任何内容。
sum(i ** 2 for i in range(10_000_000)) # generator expression — constant memory
sum([i ** 2 for i in range(10_000_000)]) # list — builds a huge list first (wasteful)
对于大型数据,生成器保持内存平坦;列表推导式一次性实现所有内容。
def count_up():
n = 0
while True: # infinite — but lazy, so it's fine
yield n
n += 1
gen = count_up()
next(gen) # 0
next(gen) # 1 — only computes when asked
由于值是按需生成的,生成器可以表示无限流——你只需取你需要的。
gen = gen_squares(3)
next(gen) # 0 — runs until the first yield
next(gen) # 1 — resumes, runs to the next yield
next(gen) # 4
next(gen) # StopIteration — generator exhausted
(x ** 2 for x in range(10)) # like a list comprehension but lazy (parentheses)
生成器对于大型或流式数据的内存高效处理至关重要——逐行读取巨大文件、处理大型数据集、管道或无限序列——其中构建完整列表会耗尽内存。
理解 yield(暂停/恢复并保留状态)和延迟求值能让你编写可扩展的数据处理代码,生成器表达式也提供了同样的好处,但更简洁。
当数据太大无法放入内存,或者你想按需处理项目而不是预先处理所有项目时,它们是关键工具。