Python的生成器

為了理解什么是 yield,你必須理解什么是生成器巧还。在理解生成器之前,讓我們先走近迭代。

可迭代對象

當你建立了一個列表悍汛,你可以逐項地讀取這個列表,這叫做一個可迭代對象:

>>> mylist = [1, 2, 3]
>>> for i in mylist :
         print(i)

mylist是一個可迭代的對象至会。當你使用一個列表生成式來建立一個列表的時候离咐,就建立了一個可迭代的對象:

>>> mylist = [x*x for x in range(3)]
>>> for i in mylist :
...    print(i)
0
1
4

所有你可以使用 for .. in .. 語法的叫做一個迭代器:鏈表,字符串奉件,文件……你經(jīng)常使用它們是因為你可以如你所愿的讀取其中的元素宵蛀,但是你把所有的值都存儲到了內(nèi)存中,如果你有大量數(shù)據(jù)的話這個方式并不是你想要的县貌。
迭代對象的定義方式通常為:

   1 # Using the generator pattern (an iterable)
   2 class firstn(object):
   3     def __init__(self, n):
   4         self.n = n
   5         self.num, self.nums = 0, []
   6 
   7     def __iter__(self):
   8         return self
   9 
  10     # Python 3 compatibility
  11     def __next__(self):
  12         return self.next()
  13 
  14     def next(self):
  15         if self.num < self.n:
  16             cur, self.num = self.num, self.num+1
  17             return cur
  18         else:
  19             raise StopIteration()
  20 
  21 sum_of_first_n = sum(firstn(1000000))

生成器

生成器是可以迭代的术陶,但是你只可以讀取它一次 ,因為它并不把所有的值放在內(nèi)存中煤痕,它是實時地生成數(shù)據(jù):

>>> mygenerator = (x*x for x in range(3))
>>> for i in mygenerator :
...    print(i)
0
1
4

看起來除了把 [] 換成 () 外沒什么不同梧宫。但是,你不可以再次使用 for i in mygenerator , 因為生成器只能被迭代一次:先計算出0摆碉,然后繼續(xù)計算1塘匣,然后計算4,一個跟一個的…

yield關(guān)鍵字

yield 是一個類似 return 的關(guān)鍵字巷帝,只是這個函數(shù)返回的是個生成器忌卤。

>>> def createGenerator() :
...    mylist = range(3)
...    for i in mylist :
...        yield i*i
...
>>> mygenerator = createGenerator() # create a generator
>>> print(mygenerator) # mygenerator is an object!
<generator object createGenerator at 0xb7555c34>
>>> for i in mygenerator:
...     print(i)
0
1
4

為了精通 yield ,你必須要理解:當你調(diào)用這個函數(shù)的時候,函數(shù)內(nèi)部的代碼并不立馬執(zhí)行 楞泼,這個函數(shù)只是返回一個生成器對象驰徊,這有點蹊蹺不是嗎笤闯。

那么,函數(shù)內(nèi)的代碼什么時候執(zhí)行呢棍厂?當你使用for進行迭代的時候.

現(xiàn)在到了關(guān)鍵點了颗味!

第一次迭代中你的函數(shù)會執(zhí)行,從開始到達 yield 關(guān)鍵字勋桶,然后返回 yield 后的值作為第一次迭代的返回值. 然后脱衙,每次執(zhí)行這個函數(shù)都會繼續(xù)執(zhí)行你在函數(shù)內(nèi)部定義的那個循環(huán)的下一次,再返回那個值例驹,直到?jīng)]有可以返回的捐韩。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市鹃锈,隨后出現(xiàn)的幾起案子荤胁,更是在濱河造成了極大的恐慌,老刑警劉巖屎债,帶你破解...
    沈念sama閱讀 212,332評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件仅政,死亡現(xiàn)場離奇詭異,居然都是意外死亡盆驹,警方通過查閱死者的電腦和手機圆丹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,508評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來躯喇,“玉大人辫封,你說我怎么就攤上這事×觯” “怎么了倦微?”我有些...
    開封第一講書人閱讀 157,812評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長正压。 經(jīng)常有香客問我欣福,道長,這世上最難降的妖魔是什么焦履? 我笑而不...
    開封第一講書人閱讀 56,607評論 1 284
  • 正文 為了忘掉前任拓劝,我火速辦了婚禮,結(jié)果婚禮上嘉裤,老公的妹妹穿的比我還像新娘凿将。我一直安慰自己,他們只是感情好价脾,可當我...
    茶點故事閱讀 65,728評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著笛匙,像睡著了一般侨把。 火紅的嫁衣襯著肌膚如雪犀变。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,919評論 1 290
  • 那天秋柄,我揣著相機與錄音获枝,去河邊找鬼。 笑死骇笔,一個胖子當著我的面吹牛省店,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播笨触,決...
    沈念sama閱讀 39,071評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼懦傍,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了芦劣?” 一聲冷哼從身側(cè)響起粗俱,我...
    開封第一講書人閱讀 37,802評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎虚吟,沒想到半個月后寸认,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,256評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡串慰,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,576評論 2 327
  • 正文 我和宋清朗相戀三年偏塞,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片邦鲫。...
    茶點故事閱讀 38,712評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡灸叼,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出掂碱,到底是詐尸還是另有隱情怜姿,我是刑警寧澤,帶...
    沈念sama閱讀 34,389評論 4 332
  • 正文 年R本政府宣布疼燥,位于F島的核電站沧卢,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏醉者。R本人自食惡果不足惜但狭,卻給世界環(huán)境...
    茶點故事閱讀 40,032評論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望撬即。 院中可真熱鬧立磁,春花似錦、人聲如沸剥槐。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至颅崩,卻和暖如春几于,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背沿后。 一陣腳步聲響...
    開封第一講書人閱讀 32,026評論 1 266
  • 我被黑心中介騙來泰國打工沿彭, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人尖滚。 一個月前我還...
    沈念sama閱讀 46,473評論 2 360
  • 正文 我出身青樓喉刘,卻偏偏與公主長得像,于是被迫代替她去往敵國和親漆弄。 傳聞我的和親對象是個殘疾皇子睦裳,可洞房花燭夜當晚...
    茶點故事閱讀 43,606評論 2 350

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