In [1]: L = [ x*2 for x in range(5)] In [2]: LOut[2]: [0, 2, 4, 6, 8] In [3]: G = ( x*2 for x in range(5)) In [4]: GOut[4]: <generator object <genexpr> at 0x632d7fb26c10>
建立 L 和 G 的區別僅在於最外層的 [ ] 和 ( ) , L 是一個列表,而 G 是一個生成器。
使用列表生成器的值常用for迴圈:
In [1]: G = ( x*2 for x in range(5)) In [2]: for x in G:..........:print(x)02468
方法2:
generator非常強大。如果推算的演算法比較複雜,用類似列表生成式的 for 迴圈無法實現的時候,還可以用函式來實現。
一.什麼是python中的生成器:
為了對比我們先來解釋一下列表生成式,透過如下方式直接建立一個列表生成式:
L = [ x*2 for x in range(5)]
但是,受到記憶體限制,列表容量肯定是有限的。如果你想建立一個包含100萬個元素的列表,一方面會佔用很大的儲存空間,另一方面,如果我們僅僅需要訪問列表中的幾個元素,那絕大多數元素佔用的空間都白白浪費了。
因此,我們需要python中提供的生成器generator,使得列表元素可以按照某種演算法推算出來,可以在迴圈的過程中不斷推算出後續的元素,這樣就不必建立完整的list,從而節省大量的空間。
二.建立生成器的方法方法1:
把一個列表生成式的 [ ] 改成 ( )
In [1]: L = [ x*2 for x in range(5)] In [2]: LOut[2]: [0, 2, 4, 6, 8] In [3]: G = ( x*2 for x in range(5)) In [4]: GOut[4]: <generator object <genexpr> at 0x632d7fb26c10>建立 L 和 G 的區別僅在於最外層的 [ ] 和 ( ) , L 是一個列表,而 G 是一個生成器。
使用列表生成器的值常用for迴圈:
In [1]: G = ( x*2 for x in range(5)) In [2]: for x in G:..........:print(x)02468方法2:
generator非常強大。如果推算的演算法比較複雜,用類似列表生成式的 for 迴圈無法實現的時候,還可以用函式來實現。
比如,著名的斐波拉契數列(Fibonacci),除第一個和第二個數外,任意一個數都可由前兩個數相加得到:
In [1]: def fib(times): ...........:n = 0 ...........:a,b = 0,1 ...........:while n<times: ...............:yield b ...............:a,b = b,a+b ...............:n+=1 ...........:return "done" ....: In [2]: F = fib(5) In [3]: next(F)Out[3]: 1 In [4]: next(F)Out[4]: 1 In [5]: next(F)Out[5]: 2三. 總結生成器節約記憶體,並且迭代到下一次的呼叫時,所使用的引數都是第一次所保留下的,即是說,在整個所有函式呼叫的引數都是第一次所呼叫時保留的,而不是新建立的。