当前位置:网站首页>那就浅浅回顾一下生成器吧
那就浅浅回顾一下生成器吧
2022-08-07 21:35:00 【华为云】
目录
一、生成器的概念
我们知道的迭代器有两种:一种是调用方法直接返回的,比如for循环就是Python自带的迭代器,一种是可迭代对象通过执行iter方法得到的,迭代器有的好处是可以节省内存。避免将大量数据一次性取出而导致的错误和内存不足问题。
如果在某些情况下,我们也需要节省内存,就只能自己写。我们自己写的这个能实现迭代器功能的东西就叫生成器。
简而言之:生成器就是我们自己写的迭代器
二、生成器函数的定义
1、yield和return关键字的区别和相同点
yield是用于生成器。什么是生成器,你可以通俗的认为,在一个函数中,使用了yield来代替return的位置的函数,就是生成器。
(1)yield和return关键字的的不同点:
它不同于函数的使用方法是:函数使用return来进行返回值,每调用一次,返回一个新加工好的数据返回给你;yield不同,它会在调用生成器的时候,把数据生成object,然后当你需要用的时候,要用next()方法来取,同时不可逆。你可以通俗的叫它"轮转容器",可用现实的一种实物来理解:水车,先yield来装入数据、产出generator object(你执行了含有yield关键字的函数,之后调用该函数不会的到返回值而是得到一个可迭代的对象"generator object")使用next()来释放;
好比水车转动后,车轮上的水槽装入水,随着轮子转动,被转到下面的水槽就能将水送入水道中流入田里。水车这个比方太恰当不过了,就是每次有个数据要取出来,先按照顺序将数据放进水车的水槽中,当后面在调用next函数的时候相当于使用水槽的水,并且是按照水车中原来进去的顺序进行取水的(先进先出)‘
(2)yield和return关键字的的相同点:
相同点:都是返回函数执行的结果
不同点:return 在返回结果后结束函数的运行,而yield 则是让函数变成一个生成器(或者叫做可迭代对象),生成器每次产生一个值(yield语句),函数被冻结,被唤醒后再产生一个值用一个栗子总结:
2、生成器函数初识
(1)什么是生成器函数
一个包含yield关键字的函数就是一个生成器函数。yield可以为我们从函数中返回值,但是yield又不同于return,return的执行意味着程序的结束,调用生成器函数不会得到返回的具体的值,而是得到一个可迭代的对象。每一次获取这个可迭代对象的值,就能推动函数的执行,获取新的返回值。直到函数执行结束。
简而言之就是函数内部含有yield关键字的就是生成器函数
(2)生成器函数的好处
生成器有什么好处就是不会一下子在内存中生成太多数据,而是你找它要它才给你值,你不向它要它也不会返回值给你。
举个栗子:
假如我预定了2000000件秋装服,我和工厂一说,工厂应该是先答应下来,然后再去生产,我可以一件一件的要,也可以一批一批的找工厂拿。而不能是一说要生产2000000件衣服,工厂一次性生产2000000件衣服在一起给我,等回来做好了,都冬天了。。。
三、生成器函数初级进阶
1、从生成器中取值的两种方法
(1)、方法一:next方法
(2)、方法二:send方法
- send 获取下一个值的效果和next基本一致
只是在获取下一个值的时候给上一个yield的位置传递了一个数据
- 使用send的注意事项:
- 第一次使用生成器时候是用next获取下一个值
- 最后一个yield不能接收外部的值
总结:
send:不能用在第一个,取下一个值的时候给上一个位置传一个新的值
2、预激协程的装饰器
什么是预激协程的装饰器?
简单来说就是个加了装饰器的生成器
预激协程的装饰器的实例:
3、Python3新加的yield from
yield from: 后接列表、生成器、协程。与asyncio.coroutine同时使用,定义协程函数。在python3.5以后改成了await。当yield from后面是IO耗时操作的时候,会切换至另一个yield from。
在这我们简单来说:yield可以在函数中代替for循环对返回的数据进行迭代
4、回顾
回顾:
一、send:
1、send的作用范围和next一模一样(从一个yield作用到下一个yield)
2、第一次不能使用send
3、函数在的最后一个yield不能接收新的值
二、
预激生成器的装饰器的例子
四、生成器函数高级进阶
1、生成器的表达式和各种推导式
(1)、列表推导式
模板:
[每一个元素或者是和元素相关的操作 for 元素 in 可迭代数据类型] 遍历后挨个处理
[满足条件的元素进行相关的操作 for 元素 in 可迭代数据类型 if 元素相关的条件] 筛选功能
(2)、生成器的表达式
- 生成器表达式(generator expression)也叫生成器推导式或生成器解析式,用法与列表推导式非常相似,在形式上生成器推导式使用圆括号(parentheses)作为定界符,而不是列表推导式所使用的方括号(square brackets)。
- 与列表推导式最大的不同是,生成器推导式的结果是一个生成器对象。生成器对象类似于迭代器对象,具有惰性求值的特点,只在需要时生成新元素,比列表推导式具有更高的效率,空间占用非常少,尤其适合大数据处理的场合。
- 使用生成器对象的元素时,可以根据需要将其转化为列表或元组,也可以使用生成器对象的next()方法或者内置函数next()进行遍历,或者直接使用for循环来遍历其中的元素。但是不管用哪种方法访问其元素,只能从前往后正向访问每个元素,不能再次访问
- 已访问过的元素,也不支持使用下标访问其中的元素。当所有元素访问结束以后,如果需要重新访问其中的元素,必须重新创建该生成器对象,enumerate、filter、map、zip等其他迭代器对象也具有同样的特点。
(3)、字典推导式
例一:将一个字典的key和value对调
(4)、集合推导式(自带结果去重功能)
2、总结
唯独没有元组推导式,要得到一个元组就可以直接将推出来的数据类型转换为元组就行
总结:各种推导式:生成器 列表 字典 集合
1、遍历操作
2、筛选操作
二、惰性运算
生成器与迭代器都是惰性运算:
但是生成器你可以看的见因为这是你写的而迭代器一般看不见
1、同一生成器中的数据只能取一次取完就没了
2、惰性运算:不找它要值它就不返回
# 列表解析
sum([i for i in range(100000000)]) # 内存占用大,机器容易卡死# 生成器表达式
sum(i for i in range(100000000)) # 几乎不占内存
1.把列表解析的[]换成()得到的就是生成器表达式2.列表解析与生成器表达式都是一种便利的编程方式,只不过生成器表达式更节省内存
3.Python不但使用迭代器协议,让for循环变得更加通用。大部分内置函数,也是使用迭代器协议访问对象的。
边栏推荐
- [笔记]机器学习之机器学习理论及案例分析《二》 聚类
- Leecode-SQL 1407. 排名靠前的旅行者
- UE4 Sequence添加基础动画效果 (03-主序列的使用)
- 【 kali - elevated privileges 】 (4.2.2) social engineering toolkit: cloning fishing web site
- 文件上传漏洞--进阶版 整理笔记
- dp数组解决背包问题
- Win7打开word提示“无法打开文件Normal因为内容有错误”怎么办
- Apache Hudi Lake Delta v: transparent TPC - DS Lakehouse performance benchmark
- win7不显示文件扩展名怎么办 win7显示文件扩展名方法
- Use phpstudy (small skin panel) to configure the record of the local PHP development environment
猜你喜欢
随机推荐
时间复杂度
打印机怎么停止打印以前的任务 怎么取消打印机正在打印的文件
autocad2007激活码序列号_激活cad2007的方法
一图了解原码、反码、补码的演进历史
怎么调整显示器刷新率_电脑屏幕怎么调刷新率
云计算学习7——云计算OpenStack运维基础
A penetration test of the BC website
Unity hot update Addressables to modify the resource cache path (download path)
双重队列问题
OpenCV 画点 画线 画框 写字操作
【Day10】进程管理命令
“那天我做了一个梦,百年后的奥运赛场上,有中国人夺冠”
OpenCV point drawing line drawing frame writing operation
win10系统玩部分老游戏时提示0xc0000022的解决方法.
温州银河证券手机开户收费吗?开户安全吗?
【无标题】
How to read ten thousand lines of code
What to do if Win7 opens word and prompts "Cannot open file Normal because there is an error in the content"
UE4 Sequence添加基础动画效果 (02-切换动作)
是时候了解下 mmap 了



![[笔记]攻防工具分享之 CobaltStrike框架 《一》环境配置](/img/d8/9983846192821000b84d68300afa68.png)




