Python 生成器:内存高效的迭代器

了解如何使用Python生成器和yield语句以最小的内存占用处理巨大的数据集。掌握生成器表达式。

在编辑器中尝试

概述

当编写处理数千或数百万条记录的代码时,内存管理变得至关重要。如果将整个数据集加载到列表中,则可能会耗尽 RAM 并使服务器崩溃。 Python 生成器通过提供按需流数据的机制解决了这个问题。生成器不是一次计算整个数据集并将其存储在内存中,而是一次生成一个项目,将其交给调用者,并暂停其执行,直到请求下一个项目。

生成器的定义与普通函数类似,但它们使用“yield”关键字而不是“return”。当调用生成器函数时,它返回一个生成器迭代器对象,而不执行函数的内部语句。当调用者在生成器上调用“next()”(或对其进行循环)时,该函数将执行直到达到“yield”。此时,生成器生成值,保存其局部变量,并暂停执行。当再次调用时,它会从上次中断的地方继续执行。

您还可以使用生成器表达式创建生成器,该表达式使用与列表推导式相同的语法,但用括号“(...)”而不是方括号“[...]”括起来。这使得用内存高效的迭代器替换列表推导式变得异常容易。通过避免大量内存分配,生成器对于处理大型日志、从数据库流式传输数据或对无限长度的数学序列执行计算是必不可少的。

代码和执行输出

生成斐波那契数的自定义生成器和内存高效的生成器表达式。

generators_demo.py
在编辑器中尝试
def fibonacci_generator(limit):
    """Yields Fibonacci numbers up to the limit."""
    a, b = 0, 1
    count = 0
    while count < limit:
        yield a
        a, b = b, a + b
        count += 1

# Instantiate generator
fib = fibonacci_generator(5)
print("--- Using Generator Function ---")
for num in fib:
    print(num)

# Generator expression (squares of numbers)
squares_gen = (x**2 for x in range(1, 1000000))
print("\n--- Using Generator Expression ---")
print(next(squares_gen))
print(next(squares_gen))
print(next(squares_gen))
端子输出
--- Using Generator Function ---
0
1
1
2
3

--- Using Generator Expression ---
1
4
9

逐步实施

  • 逐行读取对于 RAM 来说太大的文件
  • 生成 ID 或数学数字的无限序列
  • 批量流式传输数据库记录以处理 API 调用

常见问题解答

收益率和回报有什么区别?

return 完全终止函数。 Yield 产生一个值并暂停函数,保存其状态,以便在请求时可以恢复。

当生成器用完物品时会发生什么?

它引发 StopIteration 异常。在“for”循环下,Python 自动拦截此异常以干净地终止循环。

相关主题

推荐的 Python 资源

通过相关的交互式教程、备忘单和代码比较来扩展您的知识。