標籤:rom 需要 為什麼 錯誤 func instance 產生 done ext
1、列表產生式
1 [i*2 for i in range(10)]2 [fun(i) for i in range(10)]
2、產生器
1 # Author Qian Chenglong 2 3 #清單產生器 4 a=(i*2 for i in range(10)) 5 #a[1]#只是將演算法儲存了,只有在調用時才會產生相應的資料,不能直接讀取 6 a.__next__()#產生器只能一個一個往後取,且只儲存當前值 7 8 #函數產生器 9 10 # def fib(max):11 # n,a,b = 0,0,112 # while n < max:13 # print(b)14 # a,b = b,a+b15 # n += 116 # return ‘done‘17 18 #要把fib函數變成generator,只需要把print(b)改為yield b就可以了19 def fib(max):20 n,a,b = 0,0,121 while n < max:22 #print(b)23 yield b24 a,b = b,a+b25 n += 126 return ‘done‘#異常時儲存的訊息27 28 g=fib(10)29 print(g.__next__())30 #這個yield的主要效果呢,就是可以使函數中斷,並儲存中斷狀態,中斷後,代碼可以繼續往下執行,過一段時間當需要再重新調用這個函數,從上次yield的下一句開始執行。31 32 #產生器儲存的是演算法,每次調用next(g),就計算出g的下一個元素的值,直到計算到最後一個元素,沒有更多的元素時,拋出StopIteration的錯誤(異常)。33 34 #異常處理35 g = fib(6)36 while True:37 try:38 x = next(g)39 print(‘g:‘, x)40 41 except StopIteration as e:42 print(‘Generator return value:‘, e.value)43 break44 45 #通過產生器實現協程並行運算46 import time47 def consumer(name):48 print("%s 準備吃包子啦!" %name)49 while True:50 baozi = yield51 52 print("包子[%s]來了,被[%s]吃了!" %(baozi,name))53 54 55 def producer(name):56 c = consumer(‘A‘)57 c2 = consumer(‘B‘)58 c.__next__()59 c2.__next__()60 print("老子開始準備做包子啦!")61 for i in range(10):62 time.sleep(1)63 print("做了2個包子!")64 c.send(i)65 c2.send(i)#把i的值傳給yield,併到下一個yield66 67 producer("Dragon")
3、迭代器
我們已經知道,可以直接作用於for
迴圈的資料類型有以下幾種:
一類是集合資料類型,如list
、tuple
、dict
、set
、str
等;
一類是generator
,包括產生器和帶yield
的generator function。
這些可以直接作用於for
迴圈的對象統稱為可迭代對象:Iterable
。
可以使用isinstance()
判斷一個對象是否是Iterable
對象:
>>> from collections import Iterable>>> isinstance([], Iterable)True>>> isinstance({}, Iterable)True>>> isinstance(‘abc‘, Iterable)True>>> isinstance((x for x in range(10)), Iterable)True>>> isinstance(100, Iterable)False
*可以被next()
函數調用並不斷返回下一個值的對象稱為迭代器:Iterator
。
一般來說:產生器就是迭代器,迭代器不一定是產生器(下面不用看了,越看越不懂)
產生器都是Iterator
對象,但list
、dict
、str
雖然是Iterable
,卻不是Iterator
。
把list
、dict
、str
等Iterable
變成Iterator
可以使用iter()
函數:
1 >>> isinstance(iter([]), Iterator)2 True3 >>> isinstance(iter(‘abc‘), Iterator)4 True
你可能會問,為什麼list
、dict
、str
等資料類型不是Iterator
?
這是因為Python的Iterator
對象表示的是一個資料流,Iterator對象可以被next()
函數調用並不斷返回下一個資料,直到沒有資料時拋出StopIteration
錯誤。可以把這個資料流看做是一個有序序列,但我們卻不能提前知道序列的長度,只能不斷通過next()
函數實現按需計算下一個資料,所以Iterator
的計算是惰性的,只有在需要返回下一個資料時它才會計算。
Iterator
甚至可以表示一個無限大的資料流,例如全體自然數。而使用list是永遠不可能儲存全體自然數的。
Python基礎(7)——迭代器&產生器