1. 程式人生 > >day12-1 迭代器和生成器

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]) 20
next(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:  也是相當於一個迭代器。因為它不用先生成一個列表,所以感覺比較快