如何理解yield--Python提升班

要想理解yield, 須要先理解generators(生成器), 要想理解generators, 須要先理解iterables(迭代器)python

iterables

先看這段代碼:code

>>> mylist = [1, 2, 3]
>>> for i in mylist:
...    print(i)
1
2
3
>>> mylist2 = [x for x in range(3)]
>>> for i in mylist2:
...     print i
...
0
1
2

這段代碼的意思是list(列表)在python中是能夠迭代的, 若是你須要一個接一個的訪問一個數據集合, 大多數的時候使用一個for xx in yy這種方式, 那麼這裏的yy就是一個能夠迭代訪問的數據集合, 很明顯, list, tuple, string, file這些都是迭代器內存

iterables保存在內存中的, 你能夠隨便訪問他們, 好比上面的mylist,mylist2get

generators

再看這一段generator

>>> mygenerator = (x*x for x in range(3))
>>> for i in mygenerator:
...    print(i)
0
1
4
>>> mygenerator
<generator object <genexpr> at 0x10d35eaa0>

這段代碼中mygenerator就是一個迭代器, 跟上文的mylist2生成方式有點點區別, []改爲了(), 從使用上來講, generatorsiterables都是相似for in的這種方式string

可是 : generators不是保存在內存中的, 而是惰性加載的, 也就是你用到它的時候, 它才臨時去計算, 只能使用一次for in, 好比上面的mygenerator, 計算0*0並返回以後就不在保留了, 繼續計算1*1it

適用場景: 當須要迭代訪問一組量很是大的數據集的時候, generator是很是有用的, 由於它計算完了前面的數據而後就計算後面, 並不在內存裏保留全部的數據, 這樣就不至於內存爆掉io

yield

理解了generator以後, 再來看yield就很是好理解了, 能夠把yield當成return看待object

>>> def createGenerator():
...    mylist = range(3)
...    for i in mylist:
...        yield i*i
...
>>> mygenerator = createGenerator() # 建立一個生成器, 這裏createGenerator內的代碼並無運行
>>> print(mygenerator) # 生成器就是一個object
<generator object createGenerator at 0xb7555c34>
>>>
>>> for i in mygenerator: # 這裏createGenerator內的代碼纔開始運行
...     print(i)
0
1
4

上面的代碼中當調用createGenerator()的時候, 其實方法內的代碼並無運行, 而在for in循環訪問的時候, 纔開始從頭計算, 當運行到yield的時候返回第一個值, 而後就下來, 當再次請求數據的時候繼續運算直到再次碰到yield... 直到沒有值能夠返回file

參考: The Python yield keyword explained

相關文章
相關標籤/搜索