Python烧脑的生成器关键字yield怎么理解

在Python中,yield关键字用于定义生成器(generator)函数。生成器是一种特殊的迭代器,它允许你按需产生一系列的值,而不是一次性生成所有值并存储在内存中。这使得处理大数据集合时更加高效和节省资源。yield就是像一个park标识牌,遇到的时候,将当前值返回,当下一次被获取的时候,从标识牌位置往下继续运行,和循环的差别是调用一次计算一次return一次,不是全部算完。以下是yield的一些基本使用方法及代码案例:

基本使用

案例1:简单生成器

def simple_generator():
    yield 1
    yield 2
    yield 3

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

在这里插入图片描述

无限序列

案例2:生成无限序列

def infinite_sequence():
    num = 0
    while True:
        yield num
        num += 1

# 打印前10个数
for i, val in enumerate(infinite_sequence()):
    if i >= 10:
        break
    print(val)

在这里插入图片描述

计算斐波那契数列

案例3:斐波那契数列
斐波那契数列:后面的数=前两个数之和

def fibonacci(n):
    a, b = 0, 1
    for _ in range(n):
        yield a
        a, b = b, a + b

# 打印前10个斐波那契数
for num in fibonacci(10):
    print(num)

在这里插入图片描述

使用生成器表达式

案例4:生成器表达式

生成器表达式类似于列表推导式,但使用圆括号而非方括号,并返回一个生成器对象。

squared_gen = (x**2 for x in range(5))
for square in squared_gen:
    print(square)

在这里插入图片描述

作为函数参数

案例5:生成器作为函数参数

生成器可以作为需要迭代对象的函数参数。

def sum_of_squares(nums):
    return sum(x**2 for x in nums)

print(sum_of_squares(range(10)))

在这里插入图片描述

与迭代器协议结合

案例6:实现迭代器协议

通过在类中使用yield,可以创建遵循迭代器协议的类实例。

class CountDown:
    def __init__(self, start):
        self.start = start

    def __iter__(self):
        current = self.start
        while current > 0:
            yield current
            current -= 1

# 使用自定义生成器类
for num in CountDown(5):
    print(num)

在这里插入图片描述

以上是yield的一些基本用法。

下面是一些进阶用法和实际应用场合:

生成器委托(Generator Delegation)

从Python 3.3开始,生成器可以通过yield from语法委托给另一个生成器(或者任何可迭代对象),这样可以更简洁地组合多个生成器的行为。

案例7:生成器委托

def first_generator():
    for i in range(3):
        yield i

def combined_generator():
    yield from first_generator()
    yield from range(3, 6)

# 打印组合后的序列
for num in combined_generator():
    print(num)

在这里插入图片描述

生成器作为协程(Coroutines)

虽然严格意义上这不是yield的直接用法,但在Python中,生成器常被用作简单的协程,实现非阻塞的异步编程模式。通过发送值到生成器并从生成器接收值,可以模拟复杂的控制流。

案例8:生成器作为协程

def coroutine_example():
    while True:
        x = yield
        print(f"Received: {x}")

# 创建协程实例并启动
cr = coroutine_example()
next(cr) # 初始化协程,必须先调用next或send(None)
cr.send("Hello") # 发送数据到协程
cr.send("World") # 再次发送数据

在这里插入图片描述

使用生成器进行延迟计算

生成器可以用来实现惰性求值,即只在需要时计算下一个值。

案例9:延迟计算平方

def lazy_square(numbers):
    for num in numbers:
        yield num ** 2

numbers = [1, 2, 3, 4, 5]
squared_gen = lazy_square(numbers)

# 只有在迭代时才会计算平方
for square in squared_gen:
    print(square)

在这里插入图片描述

这些示例展示了yield在构建复杂逻辑、实现高效数据处理流程、以及在协程编程中的重要作用。生成器的强大之处在于它们能够灵活地控制程序的执行流程,同时保持高效的内存使用

给人的感觉和for循环的差别就是省下了内存,这个在一般情况下是用处不大的,但是在关键场景还是会发挥很大作用的,那你们有没有使用过呢?

  • 8
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

svygh123

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值