Python 生成器总结
通過列表生成式,我們可以直接創(chuàng)建一個列表。但是,受到內(nèi)存限制,列表容量肯定是有限的。而且,創(chuàng)建一個包含 100 萬個元素的列表,不僅占用很大的存儲空間,如果我們僅僅需要訪問前面幾個元素,那后面絕大多數(shù)元素占用的空間都白白浪費了。
所以,如果列表元素可以按照某種算法推算出來,那我們是否可以在循環(huán)的過程中不斷推算出后續(xù)的元素呢?這樣就不必創(chuàng)建完整的 list,從而節(jié)省大量的空間。在 Python 中,這種一邊循環(huán)一邊計算的機制,稱為生成器 generator
要創(chuàng)建一個 generator,有很多種方法。第一種方法很簡單,只要把一個列表生成式的 [] 改成 (),就創(chuàng)建了一個 generator
1. 通過表達(dá)式創(chuàng)建生成器
In [41]: g = (x for x in range(3))In [42]: type(g)
Out[42]: generatorIn [43]: g.next()
Out[43]: 0In [44]: g.next()
Out[44]: 1In [45]: g.next()
Out[45]: 2In [46]: g.next()
---------------------------------------------------------------------------
StopIteration Traceback (most recent call last)
<ipython-input-46-d7e53364a9a7> in <module>()
----> 1 g.next()StopIteration:
'''
每次調(diào)用 next(),就計算出 g 的下一個元素的值,直到計算到最后一個元素,沒有更多的元素時,拋出StopIteration的錯誤
'''
因為生成器是可迭代的,所以可以通過循環(huán)來獲取每一個值。但是你只可以迭代他們一次,不能重復(fù)迭代,因為它并沒有把所有值存儲在內(nèi)存中,而是實時地生成值:
In [18]: g = (x for x in range(3))In [19]: for i in g:...: print i...:
0
1
2
# 再一次迭代時顯示的是空值
In [20]: for i in g:...: print i...:
3. 通過函數(shù)來創(chuàng)建生成器
如果一個函數(shù)定義中包含 yield 關(guān)鍵字,那么這個函數(shù)就不再是一個普通函數(shù),而是一個 generator
generator 和函數(shù)的執(zhí)行流程不一樣。函數(shù)是順序執(zhí)行,遇到 return 語句或者最后一行函數(shù)語句就返回。而變成 generator 的函數(shù),在每次調(diào)用 next() 的時候執(zhí)行,遇到 yield 語句返回,再次執(zhí)行時從上次返回的 yield 語句處繼續(xù)執(zhí)行。
In [21]: def gen():...: for i in range(3):...: yield i...: In [22]: g = gen()In [23]: g.next()
Out[23]: 0In [24]: g.next()
Out[24]: 1In [25]: g.next()
Out[25]: 2In [26]: g.next()
---------------------------------------------------------------------------
StopIteration Traceback (most recent call last)
<ipython-input-26-d7e53364a9a7> in <module>()
----> 1 g.next()StopIteration: In [27]: g
Out[27]: <generator object gen at 0x0000000003BA0240>In [28]: gen
Out[28]: <function __main__.gen>In [29]: gen()
Out[29]: <generator object gen at 0x0000000003BA01B0>
總結(jié)
以上是生活随笔為你收集整理的Python 生成器总结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python 多线程总结(2)— 线程锁
- 下一篇: Python 高级特性 (1)- 闭包