范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

Python终结者生成器(Generator)和Yield,据说学会能加薪1000

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

Kindle回应退出中国市场传闻未接到官方通知Kindle回应退出中国市场传闻未接到官方通知中证网讯(记者董添)1月4日,有消息称,Kindle将退出中国市场。对此,Kindle方面回应中国证券报记者称,暂时没有接到退出中国市钱掌门晚间财经新闻总汇及5日周三股市早知道(附股票龙头)钱掌门财经新闻总汇,汇聚整理证券时报中证报上证报等权威讯息。今日头条CES2022将首次以单独类别展出NFT技术行业发展望提速据报道,2022年国际消费类电子产品展览会(CES)将西安捐款近2亿!民族之光Lenovo呢?大家觉得它会捐多少?诚谢提问!驰援西安抗疫大业,联想集团并没缺席,还不是一次,而是再次!联想中国通过微博发布,12月24日联想集团西安配送中心连夜调拨529台核酸检测所需IT设备,提供给西安高新疫情防OPPOFindX5系列曝光竖向内向折叠配备三款机型近日,微博著名数码博主发布消息称OPPOFindX5系列将搭载天玑9000骁龙8Gen1双平台,暂定三款机型。此外,还将有一款竖向内折的折叠屏新机,可能不属于FindX5系列,隶属OriginOSOcean有多少非常规设计?来盘点下每当我们提到手机系统的时候,相信绝大多数人都会认为苹果的iOS系统是行业标杆,在系统优化方面实力非常的优秀。虽然这种说法并没有什么不对,但大家必须要知道的是,现如今安卓系统在体验方新年焕新机!这四款手机好看又能打最低仅1499元手机中国导购不知不觉中,我们已经来到了2021年的最后一天,回想过去这一年辛勤工作的自己,购买一些新的产品犒劳自己相信也是不少人在年底的日常操作。而在这辞旧迎新的日子里,许多商家也3款手机配6000毫安大容量电池,支持反向充电,关键时可当充电宝现在人们使用手机的时间越来越长,同时手机的功耗也越来越大了,担心手机在使用时没电,经常为电池的电量而焦虑,虽然说现在的手机电池越做越大,但是也出现手机电量不足的情况,今天就为大家推5款热门iPhone旗舰手机,哪款适合你?最初的iPhone彻底改变了智能手机,从iPhone4起,每代新iPhone都对智能手机产生了重大影响。如今苹果已经发布了44款iPhone机型,无论是Apple生态系统的紧密集成查理芒格再度增持30万股阿里巴巴股份金融界1月5日消息,根据伯克希尔哈撒韦公司公布的数据显示,公司副董事长查理芒格增持了他个人在阿里巴巴的股份,此次芒格增持了30万股阿里巴巴股份。去年10月,芒格和他执掌的一家名为D地球是平的,而且是宇宙中心!盘点那些,曾被深信不疑的错误认知有人说,所谓现代科学,就是用来对固有认知进行颠覆的。人类发展至今,已有无数曾被人们奉为真理的认知,被科学的车轮无情碾碎。今天,我们就来聊聊,那些曾被深信不疑的错误认知吧!一关于宇宙这或许会成为塑料金属玻璃之后,下一个10年的主流手机材料不知道是不是机圈的竞争,越来越激烈的缘故。机哥最近有种感觉,现在大家连预热这件事,都逐渐开始不讲武德了。比如,realmeGT2系列,这发布会还没开。但给机哥的感觉却是,好像已经在
女人自信是一种精致自解放了女人,就举国上下百年来鼓励女人要自信,要独立,要做强者,以至于现在都强到男人们的肩头上了,扳着男人的双耳。想必当初提倡妇女解放的先辈们也会失落,竟为这世上开辟了造就泼妇的通四川西梓干渠提前通水灌溉,为旱区百姓引入幸福水作者刘宜峰摄影谢军日前,中国水电八局承建的四川西梓干渠项目公柘元山两条支渠提前10天成功通水,老旱区群众喜尝项目建设成果。这是继西梓干渠项目试通水成功后取得的又一重大成果,也是西梓买月影家居张继科送宏光miniEV!这样的月影灯饰你爱了吗家里装修这件事一定要上心呢,尤其是灯具的选择格外重要。因为好的灯具可以让家里充满更多的温馨。不管是白天还是晚上,优雅的灯饰品都能触碰我佛的心灵,赋予我们更多的力量。所以在选择灯具的A。O。史密斯对话设计大咖跨界聚力共筑理想人居在家居生活日趋智能化的当下,如何打造人们向往的美好生活?如何让家读懂人们的需求与喜好?如何利用智能家居技术,更好地打造理想人居?日前,由A。O。史密斯联合设计进化主办,腾讯家居丨贝A。O。史密斯携手京东家电打造静音联盟,共创生活新静界5月25日,京东家电携手A。O。史密斯等知名品牌,联合推出静音联盟,旨在聚行业之力推动家电静音标准升级,为消费者创造更舒适的静音家居生活。该活动吸引了燃气热水器空气净化器空调洗衣机盛能杰光伏逆变器荣获南德TVSDMark权威认证6月3日,在第十五届(2021)国际太阳能光伏与智慧能源(上海)展览会暨论坛期间,全球领先的第三方检测认证机构TV南德意志集团(以下简称TV南德)为深圳市盛能杰科技有限公司(以下简必要商城C2M模式开启中国制造新天地,未来发展充满可能随着科技和互联网的不断发展,加快数字化发展,改善人民生活品质成为了制造业发展的前进动力,但是现在面临制造业的转型升级,对于很多企业来说,在这个市场中怎么抓住智造业的市场机遇,探究适江苏省副省长陈星莺对七六所江苏公司发展成果给予充分肯定5月21日,江苏省副省长陈星莺赴江苏航天七零六信息科技有限公司(以下简称七六所江苏公司)调研指导工作,省政府副秘书长王思源工业和信息化厅副厅长池宇及南京市雨花台区和软件谷相关领导陪周杰伦要上市,周董背后割韭菜?深度wumiancaijing。com冲着周杰伦的名号,近两万微商大军卖减肥咖啡,让巨星传奇年入近4亿,也两次涉嫌传销被调查。周杰伦难道不担心形象受损?本文由无冕财经(wumianca北京X7综合性能表现出色,备受消费者青睐对于普通老百姓来说,买车实惠和实用最重要,在价格合适的情况下,再去考虑配置动力品牌等因素,当然如果能够花小钱办大事,那自然是再好不过了。在10万元左右的价位,很多消费者都会将自主品助力企业数字化转型实践案例七六所跨网互联解决方案2021年6月10日,由中国国际经济技术合作促进会主办,中国信息产业商会大数据产业分会中国信息化杂志社北京信息产业协会协办的2021年国有及大型企业数字化转型技术与应用大会在北京召