python中的yield使用

本文深入探讨Python中yield关键字的使用,解释yield如何将函数转换为生成器,实现高效迭代,尤其适用于处理大量数据场景。通过斐波那契数列实例,详细展示了yield的工作流程及其实现方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关于python中yield的使用,以前学习时有大概理解yield是怎么用,用文档做了笔记,但后面再看到yield时发现关于yield的理解和用法都忘记的差不多了,以前的笔记文档也没有找到,所以这里记录下关于yield的使用。

参考文章: 这里

yield的使用

yield是用在函数中的,带有yield的函数不再是一个普通函数,而是一个生成器(generator),可以用于迭代,它不像 列表 那些迭代对象,迭代时数组中所有的数据都在内存中,如果数组中有海量数据那么迭代的将非常耗内存。生成器就不一样,可以只读取它一次,在用它的时候才生成。

yield 是一个类似于return 的关键字,迭代一次遇到yield 时就返回 yield后面的值。 在下一次迭代时, 从上一次 迭代遇到的yield后面的代码开始运行,简单的说: yield就是 return 返回一个值,并且记住这个返回的位置,下次迭代就从这个位置后(下一行)开始。

下面我们通过一个斐波拉契数列的案列来看下关于yield的使用:

def fab(max):
    n, a, b = 0, 0, 1
    while n < max:
        # 运行到此处就会返回b的值,下次运行从a, b = b, a + b 这句代码开始
        yield b
        a, b = b, a + b
        n = n + 1


c = fab(10)
for i in fab(64):
    print(i)

基本通过这个案例就可以知道yield是怎么使用的了,这里如果你对yield的流程还是不怎么理解,你可以通过pycharm的Debug调试来看yield的运行。或者看下上面的那个参考文章链接

 

<think>Pythonyield关键字用于定义生成器函数。生成器函数在调用时返回一个生成器对象,该对象可以迭代以获取序列值。每次迭代时,生成器函数执行到yield语句处暂停,返回yield后的值,并在下次迭代时从暂停处继续执行。yield不仅可以从生成器函数返回值,还可以接收外部通过send()方法传入的值。</think> ### Python中的 `yield`关键字详解`yield`是Python的核心关键字,用于创建**生成器函数**。它使函数变为可暂停和恢复的状态机,在每次调用时产出值并保留执行上下文,是处理大数据流、惰性计算和协程的基石。 #### 基本工作原理 ```python def simple_counter(n): print("生成器启动") count = 0 while count < n: print(f"即将产出值 {count}") yield count # 在此暂停并返回值 count += 1 print(f"恢复执行,count={count}") # 创建生成器对象 gen = simple_counter(3) print("首次调用:", next(gen)) # 输出: 0 print("第二次调用:", next(gen)) # 输出: 1 print("第三次调用:", next(gen)) # 输出: 2 ``` 执行过程说明: 1. **首次调用 `next()`**: - 执行到 `yield count` 暂停 - 返回当前 `count(0)`,输出: ``` 生成器启动 即将产出值 0 首次调用: 0 ``` 2. **第二次调用 `next()`**: - 从 `yield` 后恢复执行 - 执行 `count += 1`,输出: ``` 恢复执行,count=1 即将产出值 1 第二次调用: 1 ``` 3. **后续调用**:类似步骤2,直至达到循环结束条件 #### 双向通信:`yield` 作为表达式 `yield` 不仅能产出值,还能**接收外部输入值**: ```python def interactive_adder(): total = 0 while True: # yield右侧返回值,左侧接收外部传入的值 value = yield total print(f"接收到值: {value}") if value is None: break total += value adder = interactive_adder() next(adder) # 启动生成器 print("当前总和:", adder.send(5)) # 输出: 5 print("当前总和:", adder.send(3)) # 输出: 8 print("当前总和:", adder.send(None)) # 结束生成器 ``` #### 高级应用场景 1. **无限序列生成** ```python def fibonacci(): a, b = 0, 1 while True: yield a a, b = b, a + b fib = fibonacci() print([next(fib) for _ in range(5)]) # [0, 1, 1, 2, 3] ``` 2. **内存高效的文件处理** ```python def read_large_file(filename): with open(filename, 'r') as file: for line in file: processed = line.strip().upper() yield processed # 逐行处理,避免内存溢出 # 处理10GB文件只需几十KB内存 for line in read_large_file('huge_log.txt'): if 'ERROR' in line: print(line) ``` 3. **状态机实现** ```python def traffic_light(): states = ['RED', 'YELLOW', 'GREEN'] index = 0 while True: signal = yield states[index] if signal == "NEXT": index = (index + 1) % len(states) light = traffic_light() next(light) # 初始化 print(light.send(None)) # RED print(light.send("NEXT")) # YELLOW print(light.send("NEXT")) # GREEN ``` #### 性能对比:生成器 vs 普通函数 ```python import sys # 普通函数:返回所有结果 def get_range(n): return list(range(n)) # 生成器函数:按需产出 def yield_range(n): i = 0 while i < n: yield i i += 1 n = 1000000 print("普通列表内存:", sys.getsizeof(get_range(n))) # 约90000KB print("生成器内存:", sys.getsizeof(yield_range(n))) # 128B(固定) ``` #### 核心特性总结 1. **惰性求值**:仅在需要时计算值 2. **状态保持**:局部变量在执行暂停间保持不变 3. **内存效率**:O(1)内存复杂度处理无限序列 4. **双向通信**:通过`send()`实现生成器与调用方交互 5. **异常处理**:支持`generator.throw()`注入异常
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值