likes
comments
collection
share

【一分钟快学】掌握 Python 生成器:使用 Yield 释放内存和性能的秘密武器

作者站长头像
站长
· 阅读数 5

在 Python 中,yield 表达式是一种非常强大的特性,允许一个函数一次返回一个值,并在下一次调用时从上次返回的位置继续执行。这种函数称为生成器。使用 yield 可以使代码更加内存高效,特别是当你需要迭代大量数据时。这是因为它不需要在迭代开始之前在内存中存储整个数据集。

如何使用 yield

基本用法

使用 yield 的函数会返回一个迭代器,每次迭代会返回一个值。

def simple_generator():
    yield 1
    yield 2
    yield 3

# 使用生成器
for value in simple_generator():
    print(value)

使用场景

当处理大型数据集时,例如从文件逐行读取数据或从数据库逐行读取记录,使用 yield 可以极大地减少内存使用。

def read_large_file(file_name):
    with open(file_name, 'r') as file:
        for line in file:
            yield line.strip()  # 去除换行符,逐行返回

# 逐行处理文件
for line in read_large_file('large_file.txt'):
    print(line)

注意点

  1. 状态保持:生成器函数在每次 yield 后暂停执行,并在下一次迭代时从上次离开的地方继续执行。
  2. 只能遍历一次:生成器是一次性的,只能遍历一次。如果需要再次遍历,你需要重新创建生成器实例。
  3. 性能考虑:虽然 yield 可以减少内存使用,但如果需要频繁访问数据或在多个地方使用数据,将所有数据加载到内存中可能更高效。
  4. 异常处理:在生成器中处理异常需要注意,因为一旦生成器开始执行,它就会在 yield 处暂停,这可能会使异常处理变得复杂。

高级用法:生成器表达式

生成器表达式提供了一种更简洁的方式来创建生成器,类似于列表推导,但使用圆括号。

# 生成器表达式
squares = (x*x for x in range(10))

for square in squares:
    print(square)

结合 yield 使用的 send() 方法

生成器不仅可以产出值,还可以通过 send() 方法接收外部传入的值,这为生成器与外界的交互提供了更大的灵活性。

def counter():
    n = 0
    while True:
        received = yield n
        if received is not None:
            n = received
        else:
            n += 1

c = counter()
print(next(c))  # 输出 0
print(next(c))  # 输出 1
print(c.send(10))  # 输出 10

通过掌握 yield 的使用,你可以编写更加高效和灵活的 Python 代码,特别是在处理大数据集、流数据或需要协程的场景中。