Python入門:生成器generator以及yield的解釋

python中若生成列表會佔用一定內存,若這個列表很大,在不使用、使用很少幾個元素的情況下會浪費一些內存,因此python設計了一個叫做生成器(generator)的東西,用來動態生成列表,根據需要產生列表元素,避免內存浪費。

同時,如果需要生成一個無限大的列表,一般方法無法滿足,也需要使用生成器。

不使用生成器生成列表

<code>		list = []
for i in range(1, 10000):
    list.append(i)
print(list)/<code>

結果:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11...]

生成器生成列表:列表推導式方式

<code># 與列表推導式不同:列表推導式是[],而生成器是()
g = (i for i in range(1, 10000))
# 獲取列表元素方法一
ele_1 = g.(__next__())
# 獲取列表元素方法二
ele_2 = next(g)/<code>

結果:1

2

生成器生成列表:函數方式

<code>def func():
    n = 0
    while True:
        n += 1
        yield n
        
g = func()
print(next(g))
print(next(g))/<code>

結果:1

2

關於yield

普通Python函數一般結束於return、函數結束或者異常,一旦函數調用結束,函數所做工作以及保存在局部變量中的數據都會丟失,再次調用這個函數,一切都將從頭創建。

yield可以看作專門給生成器使用的return,其使用方法與return大致相同,但含義有區別:

return(沒有return關鍵字的函數可認為return None)關鍵字的意思就是將控制權交還調用者。而yield可翻譯為產出、產生,其控制權的轉移是暫時的,可以理解為保存狀態+return,當再次調用時,可從保存狀態中恢復數據,繼續進行相關操作。

<code>def g():
    print('A')
    yield 1
    print('B')
    yield 2
    print('C')

for i in g():
    print(i)/<code>

結果:A

1

B

2

C

分析:for i in g()執行g()

-->print('A')打印A

-->yield 1返回值1並保存工作狀態,這裡i=1

-->print(i)打印1

-->繼續for i in g()執行g(),自yield 1保存的工作狀態下恢復繼續執行print('B'),打印B

-->yield 2返回值2並保存工作狀態,這裡i=2

-->print(i)打印2

-->繼續for i in g()執行g(),自yield 2保存的工作狀態下恢復繼續執行print('C'),打印C

-->沒有yield返回值,因此for操作接受不到值,停止操作

生成器經典例子:斐波那契數列

斐波那契(Fibonacci)數列是這樣一個數列:斐波那契數列指的是這樣一個數列 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89...。其第0項是0,第1項是第一個1,這個數列從第3項開始,每一項都等於前兩項之和。

  • 不用生成器:
<code>def fab():
    n, a, b = 0, 0, 1
    while n < max:
        print(b)
        a, b = b, a + b
        n += 1

print(fab(5))/<code>
  • 使用生成器:僅需要把print(b)改為yield b即可
<code>def fab(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        a, b = b, a + b
        n = n + 1

for n in fab(5):
    print(n)/<code>

結果相同:都是1 1 2 3 5


分享到:


相關文章: