python语法——yield 使用解析

详解 Python 中的 yield from 语法 详解 Python 中的 yield from 语法 文章目录详解 Python 中的 yield from 语法0. 参考资料1. 语法和语义描述2. 扩展了 StopIteration3. 等价代码4. 重构注意事项5. 图解分析 0. 参考资料 PEP 380 – Syntax for Delegating to a Subgenerator How Python 3.3 “yield... 阅读详情

带有 yield 的函数是一种特殊函数,其返回的函数值是一个 generator(生成器)。

yield 示例

举例说明 yield 的用法:生成一个自增平方序列:

def square(n):
    for i in range(n):
        yield i*i # 将 i*i 放入到返回值的生成器序列中

if __name__=="__main__":
    gen = square(5)
    print(type(gen)) # 打印出 gen 的类型
    while True:
        print(gen.__next__())

结果输出:

<class 'generator'>
0
1
4
9
16
Traceback (most recent call last):
StopIteration

可以看出,虽然 square 这个函数没有 return 关键字,但实际上 square(5) 是一个生成器,里面数据的顺序是按照函数中 yield 的顺序来存放的。生成器能够迭代的关键是它有一个 __next__() 方法,工作原理就是通过重复调用这个方法,直到捕获一个异常。

区别:python3 中的生成器的迭代函数为 g.__next__() 或 next(g),python2 为 g.next()。

yield原理解释

可以将 yield 理解为特殊的 return,只不过可以 yield 很多次,然后使用 __next__() 方法来读取 yield 过的这些数据。

如果一直调用 __next__ 方法,当执行到没有可迭代的值后,程序就会报错:StopIteration,所以一般不会手动的调用__next__方法,而是使用for循环:

for i in gen:
    print(i)

生成器迭代一次(通过 next 或 for 等)遇到 yield 时就返回 yield 后面的值。

重点是:下一次迭代时,从上一次迭代遇到的 yield 后面的代码开始执行。比如我们多加几个输出语句:

def square(n):
    for i in range(n):
        print(f'this is {i}')
        yield i*i # 将 i*i 放入到返回值的生成器序列中
        print(f'result is {i*i}')

if __name__=="__main__":
    gen = square(5)
    count = 0
    for i in gen:
        print(f'result:{i}')
        print(f'count:{count}\n')
        count += 1

结果为:

this is 0
result:0
count:0

result is 0
this is 1
result:1
count:1

result is 1
this is 2
result:4
count:2

result is 4
this is 3
result:9
count:3

result is 9
this is 4
result:16
count:4

result is 16

可以看到,第一次迭代和最后一次迭代的输出结果比较特殊。

第一次迭代时,生成器开始按照 square 内部代码运行,直到遇到 yield 为止,然后退出 square 函数,且返回 0。

中间的几次迭代,生成器按照 square 内部代码运行,但是是从上一次 yield 的 后一行 即 print(f'result is {i*i}') 这一行开始执行,直到遇到 yield 为止。

最后一次只输出了 result is 16 ,这是为什么呢?

这是因为,最后一次迭代时,还是从 print(f'result is {i*i}') 开始执行,但是尝试返回到循环的开头时,发现已经不满足循环条件,因此直接退出,也不会再有 yield 的结果。

yield 中 return 的作用

既然带 yield 的函数不需要 return,那么如果强制加上 return 会如何?

这时,return 会导致提前结束生成器的迭代。

比如在程序多加一行 return:

def square(n):
    for i in range(n):
        print(f'this is {i}')
        yield i*i 
        print(f'result is {i*i}')
        return i  # 多加一行return  

if __name__=="__main__":
    gen = square(5)
    count = 0
    for i in gen:
        print(f'result:{i}')
        print(f'count:{count}\n')
        count += 1

结果为:

this is 0
result:0
count:0

result is 0

第一次迭代是正常的,第二次迭代时,从 print(f'result is {i*i}') 开始运行,但是下一行 return 了,因此生成器认为整个迭代已经结束。这时候如果再调用 __next__() ,就会报错:StopIteration。

区别:python3 中 yield 函数内 return + 某个值,作用与单独的 return 相同;但是 python2 只允许单独的 return,如果后面加某个值,会报错:SyntaxError: ‘return’ with argument inside generator

备注

  • 如一个函数中出现多个 yield 则 __next__() 会停止在下一个 yield 前。
  • 使用生成器的好处:实时生成数据,不全存在内存中。
  • 使用生成器的坏处:只可以读取它一次,因为用的时候才生成。
DeepSeek API调用太复杂?OneAPI一站式聚合解决方案 本文介绍了OneAPI如何作为一站式聚合解决方案,简化DeepSeek API的调用流程。通过统一接口、智能路由和模型映射等核心功能,OneAPI大幅降低了多API适配的复杂性,提升开发效率。文章还提供了详细的部署指南和高阶使用技巧,帮助开发者快速实现API聚合管理。 阅读详情

相关推荐

新能源知识库(62)组串式、集中式和高压直挂式

因需多台PCS及独立监控设备,单位功率成本比集中式高15%–20%。高压直挂式因省去变压器,大容量项目成本更低(>5MW时优势显著)。组串式储能、集中式储能和高压直挂式储能是当前主流的三类技术路线,其核心差异源于系统架构和控制逻辑的设计差异。组串式交流侧需变压器升压至10kV/35kV,高压直挂式可直接输出6kV/35kV电压,减少转换损耗。多台小功率PCS并联(每簇独立管理)单台大功率PCS(多簇直流侧并联)环流导致容量衰减(损失5%–8%)无变压器损耗(效率>99%)高压直挂电站(≥10MW)

竹君子之家 1515

【python笔记】yield详解

yield详解: https://pyzh.readthedocs.io/en/latest/the-python-yield-keyword-explained.html https://www.jianshu.com/p/d09778f4e055 https://blog.youkuaiyun.com/dcrmg/article/details/78128041 def func(n): for i in range(0,n): val = yield i #若不调用send,.

Code_LT的博客 581

手把手教你解决Realsense D455在ROS下IMU数据不输出的问题(附固件降级指南)

本文详细解析了Realsense D455在ROS环境下IMU数据不输出的问题,提供了固件降级和ROS配置的完整解决方案。通过版本兼容性分析和实战操作指南,帮助开发者快速恢复IMU数据流,优化机器人开发体验。

weixin_42531494的博客 371

关于python中 yield item 返回最后一组数据的情况

# 错误代码: def parse(self, response): ex = '<a href="thread-(.*?)-1-1.html">' re_page = response.text re_res = re.findall(ex, re_page) for url_num in re_res[-17:]: url = 'www.baidu.com' yield scr

weixin_48759773的博客 521

FreeRTOS面试题汇总

如果一个低优先级的任务持有一个信号量,高优先级的任务想要用这个信号量,造成的死锁怎么解决。12.FreeRTOS的多任务之间如何去进行通信的,什么方法,它实现原理是什么。任务间数据传输一共有三种形式,用的最多的是消息队列,其次是全局变量和信号量。简历上写了了解RTOS,问了rtos的问题,用过哪些函数。讲解FreeRtos原理,调度机制,底层原理,代码调用。FreeRTOS,你的三个任务控制,请问你是怎么实现的。freertos中EventBits_t是干啥的?freertos使任务切换的方式有哪些?

weixin_45636780的博客 1万+

保姆级教程:用Python+OpenCV搞定Orbbec Gemini深度与彩色流对齐(附完整代码)

本文提供了一份详细的Orbbec Gemini深度与彩色流对齐教程,涵盖从环境配置到完整代码实现的每一步。通过解析深度流对齐原理,对比不同对齐模式,并提供工业级应用中的问题排查方法,帮助开发者快速掌握Orbbec Gemini相机的使用技巧。文章还包含进阶应用如点云生成与三维重建的实战代码。

weixin_29090917的博客 470

Python中的yield关键字的用法

yield 是一个类似 return 的关键字,只是这个函数返回的是个生成器。 >>> def createGenerator() : ... mylist = range(3) ... for i in mylist : ... yield i*i ... >>> mygenerator = createGenerator() # create a generator >>> print(mygenerator) # myge

升级打怪之路 393

如何制作微信小程序的在线购物商城应用

首先,你需要规划好商城的整体框架,确定好你的目标用户群体,思考他们的需求是什么。接下来,使用微信开发者工具创建一个新的小程序项目,输入你的AppID,选择好保存路径,点击“创建”,一个新的商城雏形就诞生了。你可以把这里当作自己的家,无论是工作之余的小憩,还是寻找灵感的驿站,我都希望你能在这里找到属于你的那份快乐和满足。数据是现代商业的灵魂,通过数据分析,你可以更准确地把握用户的行为模式,从而做出更明智的决策。

master_chenchen的博客 2427

解析Python中的yield关键字

前言 python中有一个非常有用的语法叫做生成器,所利用到的关键字就是yield。有效利用生成器这个工具可以有效地节约系统资源,避免不必要的内存占用。 一段代码 def fun(): for i in range(20): x=yield i print('good',x) if __name__ == '__main__': a=fun() a.__next__() x=a....

郑廿三 364

拆解一个带主动均衡的BMS模块:从变压器、MOS管矩阵到控制逻辑,图文详解内部设计与成本构成

本文深度拆解了一款带主动均衡功能的BMS模块,详细解析了其核心架构、元器件选型与成本构成。通过高频变压器、MOS管矩阵等硬件设计,该模块实现了高达87%的能量转移效率,远超普通被动均衡方案。文章还揭示了汽车级PCB设计、软件策略优化等关键技术细节,为锂电池管理系统设计提供了实用参考。

weixin_42638178的博客 347

17track单号查询逆向分析

这就说明该网站很有可能存在其它检测点,而检测本地替换最大可能的就是检测了代码格式化或者代码长度。也一样,要么导致网站卡死,要么会导致网页加载异常,这里可能就难到不少人了,让我们一步一步解决。而这个站主要是检测了代码格式化,无限循环检测造成了网站卡死,经多次测试发现检测点共三处。方法中代码很长,但是经调试后发现,它其实只返回一个固定的值,这里直接写死即可。同样的,虽然看起来很长,但是跟过之后就会发现流程很简单,这里主要就是对。追加了一些值,是一条很长的语句,整理代码。,核心流程也很简单,稍微跟一下就出来了,

pyzzd的博客 1622

Python| 理解yield关键字及示例分享

Python| 理解yield关键字及示例分享

python收藏家的博客 436

Java的API帮助文档

JDK帮助文档 SUN公司为JDK工具包提供了一整套文档资料,我们习惯上称之为JDK文档。 JDK文档中提供了Java中的各种技术的详细资料,以及JDK中提供的各种类的帮助说明。 JDk文档是Java语言的完整说明,大多数书籍中的类的介绍都要参照它来完成,它是编程者经常查阅的资料 如何理解API:就当做是一个“字典”,“使用手册”,API就相当于是一个电子的帮助文档,可以帮我们查看JDK提供的类的信息,平时查看的时候可结合百度一起看。 官网下载: 1、登录Oracle官网(Oracl.

人生得意须尽欢 2万+

python中零碎关键字语法

python中零碎关键字语法1. if else 条件判断2. for ... in 循环3. while 循环4. if else表达式5. 解析式[]{}6. 生成器表达式()7. lambda匿名函数8. yield停止当前函数执行,通常用来创建生成器函数9. yield from语法糖10. with...as语法(上下文管理) 1. if else 条件判断 简单示例: a = "a...

兰枫 296

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

列表解析与生成器与yield

列表解析 列表解析可以看做是python对于列表生成的一个语法糖,可以使得生成列表的多行代码压缩成一行,如下列表解析所示: [i for i in range(0,3)] # 输出:[0,1,2] 换成普通代码为: l = [] for i in range(0,3): l.append(i) l # 输出:[0,1,2] 这样为阅读代码以及编写带来了方便性 生成器 从形...

xiaomeng29的博客 200

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

python中的生成器与解析语法

生成器 在编程的过程中,我们常常需要一组有一定长度的有规律的数据,例如列举所有字母,等差等比数列,斐波那契数列等,这时候如果使用人工输入肯定很不现实,虽然可以通过编写一个函数来实现,但数据量一大,在所占空间上就大了,这时候就可以用到python中的yield语句,写一个生成器。生成器的语法类似于普通的函数,只不过将想要返回的值要通过yield语句来返回,并且在调用时一个通过for循环来配合。 def facotrs(n): for k in range(1,n+1): if n % k == 0:

QTT_Rookie的博客 171

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

python中yield用法和return的区别_python中return和yield怎么用的?两个有什么区别?...

匿名用户1级2009-06-08 回答常看到别人使用或讨论yield语法,能搜到的中文解释却不多,今天决心搞定yield,把暂时的理解贴到这里.搞定yield之前: 叠代器(iterator)发现yield: 生成器(constructor)使用yield: 递归调用1. iterator叠代器最简单例子应该是数组下标了,且看下面的c++代码:int array[10];for ( int i =...

weixin_39995943的博客 217

成为Python大牛必须要掌握的高端语法——yield

1. 什么是yield 在介绍yield语法之前,首先要向大家说明Python中的迭代(iteration)、可迭代(iterable)、迭代器(iterator)以及生成器(Generator)的概念: 迭代是一种对数据的操作,例如针对一个list逐一获取其中的元素的过程就叫做迭代。而可迭代是对象的一种特性,迭代操作只能针对拥有可迭代特性的对象进行,常见的可迭代对象包括数组、...

python学习者的博客 1229

python yield from 语法

python yield from 语法 yield语法比较简单, 教程也很多 , yield from的中文讲解很少 , python官网是这样解释的 PEP 380 adds the yield from expression, allowing a generator to delegate part of its operations to another generator....

weixin_30413739的博客 207

python yield form

代码: import time def generator1(): item = range(10) for i in item: yield i def generator2(): yield 'a' yield 'b' yield 'c' yield from generator1() #yield from iterab...

LodbkMi的博客 270

【Python】yield from 功能解析

yield from 是 Python 中的一个语法(PEP 380),用于简化生成器(generator)中委托子生成器的操作。它的核心作用是让一个生成器能够将部分或全部生成逻辑 “委托” 给另一个生成器,从而避免手动编写循环来逐个生成子生成器的值。

Data · Model · Agent · Repeat 1312

Python学习:yield的使用

初步认识 1、首先将yield看成一个return,即返回的操作语义; 2、其次,将yield看成一个生成器的一部分。 范例1 通过一个代码范例来演示下yield所起的作用: def foo(): print("starting...") while True: res = yield 4 print("res:",res) g = foo() pr...

Jamza的博客 155

【Python基础学习】Python生成器嵌套太多?还不使用yield from秒变简洁?!

生成器是Python中一种特殊的迭代器,允许函数在执行过程中保存状态 ,从而可以暂停并后续恢复执行。

2301_78217634的博客 1023

python3中的yield from语句

yield from的前世今生都在 这个PEP里面,总之大意是原本的yield语句只能将CPU控制权 还给直接调用者,当你想要将一个generator或者coroutine里带有 yield语句的逻辑重构到另一个generator(原文是subgenerator) 里的时候,会非常麻烦,因为外面的generator要负责为里面的 generator做消息传递;所以某人有个想法是让pytho

@_囚徒-2018_的家园 8120

从yield 到yield from再到python协程

从yield 到 yield from 再到python协程 yield 关键字 def fib(): a, b = 0, 1 while 1: yield b a, b = b, a+b yield 是在:PEP 255 -- Simple Generators 这个pep引入的 yield 只能在函数内...

weixin_30906671的博客 126
上一篇: Leetcode算法——69、sqrt(x)
下一篇: Leetcode算法——70、爬楼梯(climbing stairs)
HappyRocking
博客等级 码龄12年 222粉丝 176原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值