【python】python进阶——生成器

发布于:2025-08-29 ⋅ 阅读:(18) ⋅ 点赞:(0)

目录

一、生成器介绍

1.1 生成器与迭代器的关系

1.2 生成器与return比较

二、创建生成器

方法1: 生成器函数

方法2: 生成器表达式

三、生成器的实际应用场景

3.1 处理大型文件

3.2 生成无限序列

3.3 数据管道处理

四、生成器的高级用法

4.1 使用send()方法传递值

4.2 生成器委托(yield from)

五、生成器的特点

总结


一、生成器介绍

        生成器是Python中一种特殊的迭代器,关键字是yield,它允许你按需生成值,而不是一次性计算并存储所有值。这种"惰性计算"的特性使得生成器在处理大数据集或无限序列时非常高效。

1.1 生成器与迭代器的关系

        生成器是一种特殊的迭代器,具有迭代器的所有特性,但更简洁。生成器自动实现了迭代器协议(即__iter__()和__next__()方法),并且状态挂起和恢复是自动的。

        迭代器是一个可以记住遍历位置的对象,它从集合的第一个元素开始访问,直到所有元素被访问完结束,只能往前不会后退。生成器是使用yield表达式来生成值的函数,每次调用next()时,生成器会从上次yield的位置继续执行,直到遇到yield或return(包括函数结束)为止。

        生成器是迭代器的一种,但迭代器不一定是生成器。

  • 迭代器可以通过实现类的__iter__和__next__方法来创建
  • 生成器通过函数和yield来创建。

1.2 生成器与return比较

  • 普通函数使用return返回结果后,其执行状态就会被销毁。
  • 生成器使用yield关键字,在返回值的同时会保存当前执行状态,下次调用时可以从上次暂停的地方继续执行。

      通俗的说,yield就是和return一样执行到该位置时返回变量值,但函数不会结束退出,而是暂停在这个位置挂起任务,等待下一次next()调用时,从暂停的位置继续执行。

二、创建生成器

方法1: 生成器函数

使用yield关键字代替return的函数就是生成器函数:

def simple_generator():
    yield 1
    yield 2
    yield 3

# 使用生成器
gen = simple_generator()
print(next(gen))  # 输出: 1
print(next(gen))  # 输出: 2
print(next(gen))  # 输出: 3

方法2: 生成器表达式

类似列表推导式,但使用圆括号:

# 列表推导式 - 立即计算所有值
squares_list = [x*x for x in range(5)]  # [0, 1, 4, 9, 16]

# 生成器表达式 - 按需生成值
squares_gen = (x*x for x in range(5))
print(next(squares_gen))  # 输出: 0
print(next(squares_gen))  # 输出: 1

三、生成器的实际应用场景

3.1 处理大型文件

def read_large_file(file_path):
    """逐行读取大文件,避免内存溢出"""
    with open(file_path, 'r') as file:
        for line in file:
            yield line.strip()

# 使用生成器处理GB级文件
for line in read_large_file('huge_file.txt'):
    process_line(line)  # 每次只处理一行,不占用大量内存

3.2 生成无限序列

def fibonacci():
    """生成无限斐波那契数列"""
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a + b

# 获取前10个斐波那契数
fib_gen = fibonacci()
first_10 = [next(fib_gen) for _ in range(10)]
print(first_10)  # [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

3.3 数据管道处理

def numbers():
    for i in range(10):
        yield i

def square(nums):
    for num in nums:
        yield num ** 2

def even_filter(nums):
    for num in nums:
        if num % 2 == 0:
            yield num

# 构建数据处理管道
result = even_filter(square(numbers()))
print(list(result))  # [0, 4, 16, 36, 64]

四、生成器的高级用法

4.1 使用send()方法传递值

def generator_with_send():
    value = yield "开始"
    while True:
        value = yield f"收到: {value}"

gen = generator_with_send()
print(next(gen))      # 输出: "开始"
print(gen.send("你好"))  # 输出: "收到: 你好"
print(gen.send("世界"))  # 输出: "收到: 世界"

4.2 生成器委托(yield from)

def sub_generator():
    yield from range(3)
    yield from ['a', 'b', 'c']

for item in sub_generator():
    print(item)  # 输出: 0, 1, 2, 'a', 'b', 'c'

五、生成器的特点

优势:

  • 内存效率:一次只产生一个值,不占用大量内存

  • 惰性计算:需要时才计算,避免不必要的运算

  • 代码简洁:用简洁的语法表达复杂的迭代逻辑

  • 流水线处理:可以构建高效的数据处理管道

缺点:

  • 生成器只能迭代一次,迭代完后需要重新创建

  • 不适合需要随机访问的场景

  • 调试可能比普通函数复杂

总结

        生成器是Python中强大而高效的工具,特别适合处理大数据流、构建数据处理管道和创建无限序列。通过掌握生成器,你可以编写出更加内存友好和Pythonic的代码。


网站公告

今日签到

点亮在社区的每一天
去签到