day12-1 迭代器和生成器
通過yield實現單執行緒的情況下併發運算的效果
1 import time 2 3 def consumer(name): 4 print("%s 準備吃包子了!!" % name) 5 while True: 6 baozi = yield 7 8 print("包子[%s]來了,被[%s]吃了" %(baozi,name)) 9 #c = consumer('RI') 10 # =============================================================================通過生成器實現協程並行運算11 # c.__next__() 12 # b1 = "白菜餡" 13 # c.send(b1) # send呼叫yield 同時給yield傳值。next只會喚醒yield 14 # c.__next__() 15 # 16 # ============================================================================= 17 def producer(*name): 18 c1 = consumer(name[0]) # 呼叫函式把他變成·生成器· 19 c2 = consumer(name[1]) 20next(c1) # 為了列印 "%s 準備吃包子了!!" % name 這句話 21 next(c2) 22 print('RICH 開始做包子了') 23 for i in range(10): 24 time.sleep(i+2) 25 print('做了兩個包子') 26 c1.send(i) 27 c2.send(i) 28 print('RICH 累了,下班!') 29 30 name = ('A1','B1') 31 32 producer(*name) 33 # =============================================================================34 # 35 # 包子[8]來了,被[A1]吃了 36 # 包子[8]來了,被[B1]吃了 37 # 做了兩個包子 38 # 包子[9]來了,被[A1]吃了 39 # 包子[9]來了,被[B1]吃了 40 # RICH 累了,下班! 41 # =============================================================================
關於可迭代物件和迭代器的相關知識
可直接作用於 for 迴圈的資料型別 :
一種是資料集合型別 如 list tuple dict set str
一種是generator 包括生成器 和帶yield 的generator function
這些可直接作用於for 迴圈的物件統稱為可迭代物件 Iterable,可以使用Isinstance判斷一個物件是不是可迭代物件
1 # ============================================================================= 2 # isinstance('abc',Iterable) 3 # Out[53]: True 4 # 5 # isinstance([],Iterable) 6 # Out[54]: True 7 # 可迭代返回True 8 # =============================================================================
生成器不但可以用於for 迴圈,還可以被next()函式不斷呼叫並返回下一個值,直到最後丟擲StopIteration 的異常,表示無法進行下一個值
#可以被next()函式呼叫並返回的下一個值得=的物件成為迭代器 Iterator, 可以使用isinstance 判斷一個物件是不是可迭代物件 Iterator
1 # ============================================================================= 2 # isinstance((x+1 for i in range(10)),Iterator) 3 # Out[56]: True 4 # 5 # ============================================================================= 6
# 列表,字典 str 等式是可迭代物件,但不是迭代器
# 把可迭代物件變為迭代器 可以使用Iter() 函式
1 a = [1,2,3,4] 2 3 b = iter(a) 4 5 isinstance(a,Iterator) 6 Out[59]: False 7 8 isinstance(b,Iterator) 9 Out[60]: True
python 的Iterator 物件表示的是一個數據流,Itrator物件可以被next()函式呼叫並不斷返回下一個資料,直到沒有資料時丟擲StopIteration 錯誤。可以把資料流看做是一個有序序列。
但是我們不知道有序序列的長度,只有通過next()不斷呼叫計算下一個資料。所以Iterator 是惰性的,只有在需要時才會返回下一個資料時他才會計算。
Iterator 甚至可以返回一個無限大的資料流。例如全體自然數,而list是永遠不可能儲存全體自然數的
小結:
可以作用於for迴圈的就是Iterable型別
凡是可以作用於next()物件的則是Iterable型別。表示一個惰性計算的序列
Iterable 物件可以通過iter()獲得iterator物件
python for迴圈的本質是通過不斷呼叫next()函式實現的
1 for i in [1,2,3,4,5,6]: 2 print(i) 3 4 # 相當於 5 it = iter([1,2,3,4,5]) 6 7 while True: 8 try: 9 x = next(it) 10 print("it",x) 11 except StopIteration: 12 break 13 14 15 # ============================================================================= 16 # 1 17 # 2 18 # 3 19 # 4 20 # 5 21 # 6 22 # it 1 23 # it 2 24 # it 3 25 # it 4 26 # it 5 27 # =============================================================================
t = range(10)
也是相當於迭代器,檢視檔案 for line in f: 也是相當於一個迭代器。因為它不用先生成一個列表,所以感覺比較快