python生成器(generator)

1.生成器(generator)概念

生成器是迭代器馒稍,生成器提供了非常方便的自定義迭代器的途徑,在Python中,這種一邊循環(huán)一邊計(jì)算的機(jī)制缓艳,稱為生成器(Generator)

2.生成器作用

通過(guò)列表生成式昂秃,我們可以直接創(chuàng)建一個(gè)列表椎瘟。但是,受到內(nèi)存限制呀潭,列表容量肯定是有限的钉迷。而且,創(chuàng)建一個(gè)包含100萬(wàn)個(gè)元素的列表钠署,不僅占用很大的存儲(chǔ)空間糠聪,如果我們僅僅需要訪問(wèn)前面幾個(gè)元素,那后面絕大多數(shù)元素占用的空間都白白浪費(fèi)了谐鼎。所以舰蟆,如果列表元素可以按照某種算法推算出來(lái)趣惠,那我們是否可以在循環(huán)的過(guò)程中不斷推算出后續(xù)的元素呢?這樣就不必創(chuàng)建完整的list身害,從而節(jié)省大量的空間.

比如味悄,著名的斐波拉契數(shù)列(Fibonacci),除第一個(gè)和第二個(gè)數(shù)外塌鸯,任意一個(gè)數(shù)都可由前兩個(gè)數(shù)相加得到:
1, 1, 2, 3, 5, 8, 13, 21, 34, ...

斐波拉契常規(guī)函數(shù)寫法:
In [18]: def fib(num):
    ...:     a,b,n=0,1,0
    ...:     while n<num:
    ...:         print(b)
    ...:         a,b=b,a+b
    ...:         n+=1
    ...:

In [19]: fib(5)
1
1
2
3
5

3.生成器創(chuàng)建

常見(jiàn)的生成器創(chuàng)建有兩種形式:
①生成器表達(dá)式
②生成器函數(shù)

3.1.生成器表達(dá)式

生成器表達(dá)式與列表解析式極為相似,將列表解析式'[]'改成'()'就是一個(gè)生成器,生成器擁有next方法并且行為與迭代器完全相同侍瑟,這意味著生成器也可以用于Python的for循環(huán)遍歷,看

In [16]: gen=(x*x for x in range(4))
In [17]: gen
Out[17]: <generator object <genexpr> at 0x00000000045335E8> #結(jié)果表明為生成器
In [18]: for i in gen :
                print(i),
  
#執(zhí)行結(jié)果
0 1 4 9
3.1.生成器函數(shù)

生成器函數(shù)與普通函數(shù)極為相似,若函數(shù)中包含了至少一個(gè)yield關(guān)鍵字則為生成器,通過(guò)生成器函數(shù)可實(shí)現(xiàn)復(fù)雜邏輯的generator,例:

#定義一個(gè)生成器
In [1]: def gen():
      print('start')
      for  i  in  range(5):
            yield i               #帶yield關(guān)鍵字
            print(i)
      print('end')
------------------------------------------------------------------------------
In [2]: gen()
Out[2]: <generator object gen at 0x0000000004533C18>   #結(jié)果表明為生成器
In [3]: t=gen()
In [4]: next(t)                 #每次進(jìn)行迭代時(shí)返回一個(gè)值
start
Out[4]: 0
In [5]: next(t)
0
Out[5]: 1
In [6]: next(t)
1
Out[6]: 2
In [7]: next(t)
2
Out[7]: 3
In [8]: next(t)
3
Out[8]: 4
In [9]: next(t)
4
end
--------------------- 執(zhí)行到末尾,迭代器遇到StopIteration異常結(jié)束
StopIteration                             Traceback (most recent call last)
<ipython-input-9-9494367a8bed> in <module>()
----> 1 next(t)
StopIteration:

4.生成器函數(shù)執(zhí)行過(guò)程

生成器函數(shù)中的yield關(guān)鍵字包含兩種功能:

1.返回
2.掛起

[L1] def gen():
[L2]      print('start')
[L3]      for  i  in  range(5):
[L4]            yield i              
[L5]            print(i)
[L6]      print('end')

1.第一次執(zhí)行next(generator)時(shí),會(huì)執(zhí)行完yield語(yǔ)句后程序進(jìn)行掛起丙猬,所有的參數(shù)和狀態(tài)會(huì)進(jìn)行保存
2.再一次執(zhí)行next(generator)時(shí)涨颜,會(huì)從掛起的狀態(tài)開(kāi)始往后執(zhí)行。
在遇到程序的結(jié)尾或者遇到StopIteration時(shí)茧球,循環(huán)結(jié)束

yield 與 return

5.生成器自帶方法屬性

#在ipython中對(duì)之前創(chuàng)建的gen生成器對(duì)象查看幫助
In [20]: help(gen)
Help on generator object:
<genexpr> = class generator(object)
 |  Methods defined here:
 |
 |  __getattribute__(...)
 |      x.__getattribute__('name') <==> x.name
 |
 |  __iter__(...)
 |      x.__iter__() <==> iter(x)
 |
 |  __repr__(...)
 |      x.__repr__() <==> repr(x)
 |
 |  close(...)
 |      close() -> raise GeneratorExit inside generator.
 |
 |  next(...)
 |      x.next() -> the next value, or raise StopIteration
 |
 |  send(...)
 |      send(arg) -> send 'arg' into generator,
 |      return next yielded value or raise StopIteration.
 |
 |  throw(...)
 |      throw(typ[,val[,tb]]) -> raise exception in generator,
 |      return next yielded value or raise StopIteration.
 |
 |  ----------------------------------------------------------------------
 |  Data descriptors defined here:
 |
 |  gi_code
 |
 |  gi_frame
 |
 |  gi_running

通過(guò)上面的幫助文件可以歸納出生成器的方法有

1.close()
手動(dòng)關(guān)閉生成器函數(shù)庭瑰,后面的調(diào)用會(huì)直接返回StopIteration異常。
2.send()
生成器函數(shù)最大的特點(diǎn)是可以接受外部傳入的一個(gè)變量抢埋,并根據(jù)變量?jī)?nèi)容計(jì)算結(jié)果后返回
3.throw()
用來(lái)向生成器函數(shù)送入一個(gè)異常弹灭,可以結(jié)束系統(tǒng)定義的異常,或者自定義的異常揪垄。
throw()后直接跑出異常并結(jié)束程序穷吮,或者消耗掉一個(gè)yield,或者在沒(méi)有下一個(gè)yield的時(shí)候直接進(jìn)行到程序的結(jié)尾饥努。

6.yield from

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末酒来,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子肪凛,更是在濱河造成了極大的恐慌堰汉,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,104評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件伟墙,死亡現(xiàn)場(chǎng)離奇詭異翘鸭,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)戳葵,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門就乓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人拱烁,你說(shuō)我怎么就攤上這事生蚁。” “怎么了戏自?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,697評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵邦投,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我擅笔,道長(zhǎng)志衣,這世上最難降的妖魔是什么屯援? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,836評(píng)論 1 298
  • 正文 為了忘掉前任,我火速辦了婚禮念脯,結(jié)果婚禮上狞洋,老公的妹妹穿的比我還像新娘。我一直安慰自己绿店,他們只是感情好吉懊,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著假勿,像睡著了一般惕它。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上废登,一...
    開(kāi)封第一講書(shū)人閱讀 52,441評(píng)論 1 310
  • 那天,我揣著相機(jī)與錄音郁惜,去河邊找鬼堡距。 笑死,一個(gè)胖子當(dāng)著我的面吹牛兆蕉,可吹牛的內(nèi)容都是我干的羽戒。 我是一名探鬼主播,決...
    沈念sama閱讀 40,992評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼虎韵,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼易稠!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起包蓝,我...
    開(kāi)封第一講書(shū)人閱讀 39,899評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤驶社,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后测萎,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體亡电,經(jīng)...
    沈念sama閱讀 46,457評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評(píng)論 3 341
  • 正文 我和宋清朗相戀三年硅瞧,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了份乒。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,664評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡腕唧,死狀恐怖或辖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情枣接,我是刑警寧澤颂暇,帶...
    沈念sama閱讀 36,346評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站但惶,受9級(jí)特大地震影響蟀架,放射性物質(zhì)發(fā)生泄漏瓣赂。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評(píng)論 3 334
  • 文/蒙蒙 一片拍、第九天 我趴在偏房一處隱蔽的房頂上張望煌集。 院中可真熱鬧,春花似錦捌省、人聲如沸苫纤。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,511評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)卷拘。三九已至,卻和暖如春祝高,著一層夾襖步出監(jiān)牢的瞬間栗弟,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,611評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工工闺, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留乍赫,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,081評(píng)論 3 377
  • 正文 我出身青樓陆蟆,卻偏偏與公主長(zhǎng)得像雷厂,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子叠殷,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 我們可以通過(guò)列表生成式簡(jiǎn)單直接地創(chuàng)建一個(gè)列表改鲫,但是受到內(nèi)存限制,列表容量肯定是有限的林束。而且像棘,創(chuàng)建一個(gè)包含100萬(wàn)個(gè)...
    PyChina閱讀 2,865評(píng)論 0 3
  • 通過(guò)對(duì)廖雪峰的python教程學(xué)習(xí)生成器,如下代碼: 輸出內(nèi)容如下: generator函數(shù)壶冒,在每次調(diào)用next(...
    camlboy閱讀 1,595評(píng)論 0 0
  • 一讲弄、迭代器iterator 1.簡(jiǎn)介: 迭代器是訪問(wèn)集合內(nèi)元素的一種方式。迭代器對(duì)象從集合的第一個(gè)元素開(kāi)始訪問(wèn)依痊,直...
    ikaroskun閱讀 510評(píng)論 0 1
  • 生成器(Generator)可以說(shuō)是在 ES2015 中最為強(qiáng)悍的一個(gè)新特性避除,因?yàn)樯善魇巧婕暗?ECMAScri...
    Will_Wen_Gunn閱讀 4,746評(píng)論 0 9
  • 13/365(2016.12.28)#HR修煉# 又到年終歲尾瓶摆,你是在寫年終總結(jié),還是在制定下一年工作計(jì)劃呢性宏?16...
    魔法豆閱讀 287評(píng)論 1 3