游戏电视苹果数码历史美丽
投稿投诉
美丽时装
彩妆资讯
历史明星
乐活安卓
数码常识
驾车健康
苹果问答
网络发型
电视车载
室内电影
游戏科学
音乐整形

Python终结者生成器(Generator)和Yield,

  来源:麦叔编程
  作者:麦2叔
  先来学几个英文单词,本文统一使用英文单词表示以下概念:Iterable:可迭代对象Iterator:迭代器Generator:生成器
  本文的重点是Generator,之所以上来就说这3个概念,是因为:Generator只不过是Iterable和Iterator的一种简单形式。
  用类的形式写IterableIterator,要定义类,并包含至少三个函数:init,iter和next,但用Generator只要定义一个函数就搞定了。
  我在面试Python程序员的时候,连续几个号称资深的程序员,回答Generator的问题都回答的不好。如果你能理解透彻这篇文章,对你的加薪作用可能不止一千。
  虽然有标题党的嫌疑,但具有实在的意义。所以既然进来了,就耐心读下去吧。一周能理解透一个重要概念,假以时日,你就是高手。Generator是IterableIterator的简单写法
  如果你对Iterable和Iterator一无所知,建议先阅读本文的姊妹篇:Python终结者2可迭代对象(iterable)vs迭代器(iterator)vs生成器(Generator)
  我们先用IterableIterator的方式来定一个随机数生成器,我把它命名为Randable,它的功能是:随机生成若干个1到100之间的随机数。
  importrandomclassRandable():definit(self,total):self。count0self。totaltotaldefiter(self):returnselfdefnext(self):ifself。countself。total:raiseStopIterationrandnumrandom。randint(1,100)self。count1returnrandnum
  使用上面的Randable类生成88个随机数:foriinRandable(88):print(i)
  这是一个类,包含init,iter和next3个函数:Randable(100)调用init函数创建了一个可以生成100个随机数的对象。for语句循环这个对象的时候首先调用iter函数获取Iterator,也就是这个对象本身。然后for不停调用next函数做循环,直到抛出StopIteration异常。
  整个过程有点小复杂,也难以理解。Generator的出现就是为了简化这种复杂的写法。
  实现同样的功能,Generator只需要一个函数就够了:defrandgen(total):forinrange(0,total):yieldrandom。randint(1,100)
  调用过程不变:foriinrandgen(88):print(i)Generator的原理
  for循环过程
  结合上面的Geneator的例子,我们看一下for循环的过程:调用generator函数randgen(88):,并不会马上执行函数中的代码,而是返回一个generator对象。for循环通过Python内置的next函数调用这个对象,直到对象抛出StopIteration异常为止。
  试验一下:defrandgen(total):forinrange(0,total):yieldrandom。randint(1,100)grandgen(88)print(type(g))
  执行上面这段代码,会打印出:classgeneratorGenerator特征Generator函数中没有return语句,只有yield语句。所以生成器就是:有yield关键词的函数。Generator也可以有return语句,return语句就相当于抛出了StopIteration异常,会结束函数。使用next()函数执行Generator中的代码,上面的for循环也是这个原理。当代码执行到yield语句的时候,yield会返回一个值给调用者,然后函数暂定在原地,等待下次调用。下次调用会从上次暂定的地方继续执行代码。这个过程会重复直到所有代码都执行完成,或者抛出了异常。
  来看一个例子:Generatordefthreestep():print(这是第一步,你好!!)yieldprint(这是第二步,你还好吗?)yieldprint(这是第三步,再见!)sthreestep()next(s)next(s)next(s)
  运行一下,打印的结果如下:第一次调用这是第一步,你好!!第二次调用这是第二步,你还好吗?第三次调用这是第三步,再见!Traceback(mostrecentcalllast):FileUserszjuemangitpythonweixingeneratorgen。py,line47,inmodulenext(s)StopIteration
  说明一下:yield关键词会让函数暂停,也可以没有返回值可以把generator理解成有状态的函数。一般的函数没有自己的状态,执行一次就结束了。但是generator有自己的状态可以被多次调用。实际上Generator背后就是一个类,所以它有状态。上一节中我们说过,Generator就是IterableIterator类的一种简单写法。Generator表达式
  Genertor除了函数的写法之外,还可以用表达式的写法。它的写法和列表推导式类似,区别就是把中括号〔。。。〕改成小括号(。。。)。
  这是一个列表推导式:importsys生成1到1万的数字的平方numssquaredlist〔i2foriinrange(10000)〕
  这是Generator表达式:importsys生成1到1万的数字的平方numssquaredgen(i2foriinrange(10000))
  前者会在内存中生成10000个数字,放在列表中。
  后者不会马上生成,当你每次用next(numssquaredgen)函数去调用它的时候,它会生成一个并返回。
  如果你对推导式不熟悉,请看终结者系列的另一篇文章。链接见文末。Generator的性能优势
  Generator因为可以被循环,经常被拿来和list做对比。它最让人津津乐道的是它的性能优越性。
  假如你开了一家汉堡店,有个大客户向你订购1000万个汉堡。你会一次性生产完这些汉堡吗?
  傻的汉堡店主会这样:一次性生产完1000万个汉堡,可是店里根本放不下啊。再租个仓库放。可是后来发现汉堡都坏掉了。
  聪明的汉堡店主会这样:分批生产!客户什么时候来要,就给他们马上生产一批,既不会把店占满,汉堡还新鲜!
  那如果有个需求,让你生成100亿个随机数,再求和。你会这样写吗?请不要尝试下面的代码,因为你的电脑可能会卡死!!!randnums〔〕foriinrange(1,10000000000):randnums。append(random。randint(1,100))print(sum(randnums))
  如果这样写,你的程序会在内存中生成100亿个整数,这也许会占满你的内存。
  正确的写法是使用Generator,就用我们上面的randgen吧:print(sum(randgen(10000000000)))
  前面使用list的时候,要先在内存中生成100亿个数字,然后再求和,这占空间又费时间。
  而用Generator是每次用到的时候才生成1个,不用那么多空间。
  我们可以测试一下前面的推导式的例子中占用的内存情况:importsysnumssquaredlist〔i2foriinrange(10000)〕sys。getsizeof(numssquaredlist)87624列表推导式占用了87624字节的内存numssquaredgen(i2foriinrange(10000))print(sys。getsizeof(numssquaredgen))120Generator只占用了87624字节的内存
  这个例子中只生成10000个数字,区别还没那么大。如果是生成100亿个数字,区别会更大,因为Generator占用的内存基本是恒定的,和数字多少无关。
  如果你曾经在写代码的时候犯了傻汉堡店主的问题,那么不要羞愧,因为Python语言的设计者们都犯过这样的错误!
  在Python2中很多标准库使用列表形式,出现内存问题。所以在Python3中很多标准库都改用了Generator。
  比如:range()函数在Python2中返回的是一个列表,在Python3中返回的是一个Genator。字符串的迭代器也是一个Generatorprint(iter(abcpython终结者2))print(iter(range(1,10000)))
  打印结果:striteratorobjectat0x7fa30ba3e3a0rangeiteratorobjectat0x7fa30ba3e2d0帮你熟悉Generator的几个代码例子
  我们再来多看几个代码例子,有的很简单,目的是为了给你增加更多的代码感觉。range是一个Generator,所以多大的range内存都不会爆foriinrange(5):
  print(i)三次方生成器defmygenerator(n):
  foriinrange(1,n,2):
  yieldi3表达式形式的三次方生成器mygenerator(i3foriinrange(1,10,2))Generator不只是用在for循环中,我们可以手动用next()函数调用它defmygenerator(n):
  foriinrange(1,n,2):
  yieldi(i1)
  mygenmygenerator(6)
  next(mygen)
  2hrnext(mygen)
  12hrnext(mygen)
  30hrnext(mygen)
  StopIterationerror高级的Generator方法
  普通的Generator执行到yield就暂停,可以返回一个值或者不返回。
  Generator除了可以返回值,它还可以接收调用者传值进来,这就要使用send()方法。
  除了send()方法,还有throws,close()方法。
  能通过yield返回值,也能够通过send()接收值,这就不是普通的Generator,而是进入了协程coroutine的领域了,需要专门的文章来讲,我们下次再终结。
  基本的Generator有上面这些知识就足够了。

张大佛爷为什么灭九门老九门死亡顺序?《老九门》这部剧相信很多人都略有所闻的吧,剧情可真是太精彩了,而且演员们的表现也都很出色,那么大家知道张大佛爷为什么灭九门吗?还有就是结局九门的确被灭了,那么老九门死亡顺序是什……老九门丫头怎么死的老九门丫头得的什么病看过老九门的都知道,在电视剧《老九门》中,张启山不惜散尽家产,之位给二月红的夫人丫头求药,那么最后还是死了,老九门丫头怎么死的?老九门丫头得的什么病?今天就和小编一起来看看吧。……互联网与你我他范文互联网与你我他在中国,科技的进一步发展,互联网的迅速普及,瞬间进入了千家万户,在全国,互联网更是一种社会上的竞争,也成为与我们息息相关的一项任务性工作。在腾讯、新浪……狗狗币可能超越下一个比特币或虚拟市场近期以来,狗狗币却突然迅速起飞了,现在以总市值计,已经挤进了虚拟货币的前十名。今年早些时候,狗狗币的价格一度冲上了近74美分的历史最高点。虽然狗狗币近期知名度和价格双双猛增,但……余生请多指教什么时候播出,余生请多指教男主角叫什么余生请多指教说出来很多人不清楚,可余生请多指教电视剧是什么时候播出,很多网友就想去了解一下有关的故事,看余生请多指教早都拍出,之后就一直不公布上映的时间出,但有的网友就不清楚余……后来的我们电影台词很多人的经历后来就没有后来了后来的我们电影台词:很多人的经历后来就没有后来了《后来的我们》是由刘若英执导,张一白监制,井柏然、周冬雨、田壮壮主演的青春文艺片。该片讲述了一对男女在过年回家的火车上相识……上九天揽月是什么意思出自哪里后来的我们诠释了什么上九天揽月是什么意思出自哪里:后来的我们诠释了什么电影《后来的我们》可谓十分火热,影片除了精彩的剧情吸引观众外,同时影片中的经典台词ldquo;上九天揽月,下五洋捉鳖rd……纯电动汽车的滑行回馈当前主流车企的纯电动汽车,都会有滑行回馈功能,这是为了将动能转换为电能,提高电动汽车的续航里程,一般滑行回馈功能是由VCU(整车控制器)控制的,基本是松开油门后,车辆滑行过程中……抢在iPhone13前上市?三星GalaxyS21FE主要规去年三星推出GalaxyS20FE,成绩相当不俗,今年三星传闻GalaxyS21FE已决定抢先苹果iPhone13,在9月8日正式上市,而于海外的三星专卖店内,也已曝光了产品的……iPhone15或将全部搭载苹果自研芯片3nmA175nm自在去高通化的道路上,苹果一直没有停歇。近日,中国台湾工商时报援引供应链消息称,将于2023年发布的iPhone15将首次全部采用苹果自研芯片,除了A17将采用台积电3nm……用于下一代信息处理的相干门研究人员已经设计出一种改进的方法,可以在磁头和微波光子之间进行更好的信息传输,这可能会在信号交换、低功耗计算和量子网络方面带来进步。栅极驱动在电子学中非常重要。栅极本质上……数字人民币APP下载量猛增,这到底是啥?跟我们有何关系?这个APP有利于国家对个人资产的掌控。有利于国家在世界金融市场对抗美国金融霸权。对国家整体金融安全和我国在世界金融市场的地位有很大帮助。总之战略层面的益处。使用起来感觉想……
第四艘超级航母正式官宣首块钢板切割,将搭载五代机和无人战机8月25日,美国海军的第4艘福特级航空母舰正式开始建造。相关人员参加了在纽波特纽斯船厂的第一块钢板切割仪式。美国海军计划用新一代福特级航母替换尼米兹级航母,未来,福特级航母将成……藤编花篮,让花草绿植成为一门艺术拥有古老发展历史,传统制作工艺的藤编,除了融合新的设计语言,成为时尚圈和家居圈的宠儿以外,它还可以回归本真,成为我们生活中最常见的手工艺品。老式藤椅、菜篮、手持蒲扇、花篮……蓝牙鼠标享受手机待遇,雷柏新品MT750pro近日雷柏推出了MT750PRO,这是基于MT750S的升级版本,外形没什么变化,也依然是2。4G、蓝牙3。04。0的双模无线,但新增了QI协议无线充电,并成功减重8g。双……云徙技术平台V3。6版本更新,后端测试效率再次提升8月6日,云徙科技宣布产品更新,正式发布技术平台V3。6版本。在技术平台V3。6版本中,数字化研发服务平台(iDP)测试管理中新增了自动化接口测试相关模块,重点包括:……奔驰进军纯电MPV!纯电MPV将成为新能源汽车的下一个战场?文Lei新能源汽车市场到底饱和了吗?这句话或许已经成为了很多人心中的疑问。实际上,从新能源汽车市场渗透率和源源不断地进入新能源汽车市场的创业者们看,新能源汽车仍然是一个非……Fooview一款功能超多的桌面悬浮球,帮你摆脱多余操作今天给大家推荐的这款软件是Fooview,也叫做FV悬浮球,适合于安卓端,这款软件非常的强大,不能认为它就是一个普普通通的悬浮球软件。它除了是悬浮球工具外,还有很多其它的……科技让教育更美好,跟谁学宣布更名高途,这些理念让人赞叹4月22日,在线教育上市公司跟谁学在北京国家会议中心召开媒体发布会,宣布更名为高途集团。更名后,高途集团K12在线教育品牌为高途课堂,成人在线教育品牌为高途学院。高途集团是中国……浅谈WindowsPhone为何失败自从iOS问世以来,智能移动终端的市场就打得不可开交,在此之前,一直都是塞班系统的天下,其他系统可以用忽略不计来形容。当看到手机端有这么大一片市场,作为PC系统老大的微软也想分……三款可盲选的热销车,SUV入门代步都有,最低3万多即可落地相信不少朋友都有过这样的情况,在确定了预算和选车方向后就迷失了方向,面对如此多的车型、品牌就不知道该怎么选。其实,若您没有对某一品牌或某一款车有着极大的兴趣,那么完全就可考虑同……HarmonyOS用户数突破一亿,用时100天9月13日晚,华为余承东在华为智慧办公新品发布会上宣布:截至9月12日,用时100天,HarmonyOS2升级用户数突破1亿。距离2021年底搭载HarmonyOS的设备达到4……巩义一个村庄建了一所大学,今年招生位于河南省巩义市的米河镇,近年被正商集团承包,其中一个村庄叫做草店村,位于米河镇的北部,正商集团投资高达十亿来建这所学校,学校名称为郑州正商职业学院。这所大学的建筑面积规……新壶装旧酒,越品越香?酷冷至尊MB400L装机记说起我前年装的这台主机,真把我折腾的不轻。先是电源买回来,安装不下,只好联系客服换成小功率款;夏天机箱烫手,我添了两把散热风扇,发现不管用,最终把R9380大火炉换成了G……
友情链接:易事利快生活快传网聚热点七猫云快好知快百科中准网快好找文好找中准网快软网