python(生成器)

生成器函數

先從列表生成式提及spa

 

 能夠經過簡單的式子,生成有規律的列表code

若是把 [ ] 換爲 ( ) 會發生什麼呢?對象

 

看到 x 存的再也不是列表,而是一個地址,而這個地址就是咱們的生成器對象的地址blog

這東西有什麼用呢? 固然時,節省內存啦內存

假設如今有很龐大的一組數據要處理,貌似不可能把它一次性載入內存再進行處理,這時候就體現出了生成器的好處,由於它只佔用一個數據的內存空間,當須要訪問下一個class

數據時,當前的數據會被覆蓋掉,因此有多少數據都無所謂啦,都是能夠處理的。能夠經過 next() 或 __next__() 方法訪問下一個數據。import

固然仍是要藉助循環來進行對元素的訪問,100w個數據不可能敲一百萬個 next() 吧。循環

 

 

固然若是這些數據不能用表達式表示怎麼辦?答案就是用函數 + yield 關鍵字,有yield關鍵字的函數就是一個生成器。yield

來個栗子(打印斐波那契數列):

 

yield a 能夠理解爲返回一個a,但會記下當前代碼的位置,下次將從yield a 的下一句開始執行代碼。拿這段代碼來講,從最後的循環提及。

1.next() 方法啓動生成器,生成器要執行一次

2.程序進入wile循環

3.遇到yield a 返回a值並幾下斷點

4.for 循環的print語句受到a的值打印a=1

5.for繼續循環,有調用了next()方法,生成器再次啓動

6.生成器找到上次斷點的位置執行代碼(a,b = b,a+b)...

7.再次遇到yield語句,回到步驟 3

......

除了 next()方法 ,send ( )也能夠啓動生成器,可是send能夠給生成器傳值,而這個值將強制替換上次斷點的處的返回值

 

看到 send 傳入的參數替換的是 res 的值,而不是 a 的值!!!,至於爲何會打印 ‘None’ 其實 next 默認傳入一個 None 因此一調用 next() 就會打印 None,而調用 send 則

打印 sned 傳入的參數。

最後來一個經典的生產者消費者問題吧

 

 1 import time
 2 def consumer(name):
 3     print("%s is ready to consume" % name)
 4     while True:
 5         res = yield
 6         print("%s has consumed goods %d" % (name,res))
 7 def producer(name):
 8     print("%s is ready to produce" % name)
 9     while True:
10         time.sleep(3)
11         succ = yield 
12         print("produce goods %d and goods %d successfully" % (succ,succ+1))
13 c1 = consumer('c1')
14 c2 = consumer('c2')
15 c1.__next__()
16 c2.__next__()
17 p1 = producer('p1')
18 p1.__next__()
19 for i in range(10):
20     p1.send(i+1)
21     c1.send(i+1)
22     c2.send(i+2)
相關文章
相關標籤/搜索