首先從一段**來簡單看下什麼是生成器:
生成器與列表不同,生成器不會靜態地在記憶體中建立元素,它有點類似於函式,只輸出結果而不建立結果。想要檢視生成器輸出的所有元素,使用for迴圈:
for
item
in g:
print(item)
取前n個元素:
for i in range(10):
print(g.__next__())
for j in range(10):
print(g.__next__())
.next()方法是使生成器輸出單個元素,同時生成器會記錄工作指標,上段**實際上輸出了[0,19]。生成器只能順序輸出,無法倒序輸出,更無法隨機輸出。
對於複雜邏輯,不可能使用類似列表的語句來生成資料,需要用到函式生成器。當函式中存在yield關鍵字時,函式會變成乙個生成器,yield會將其修飾的變數進行輸出。對於函式生成器的.__next__()
方法,它會使函式生成器執行到yield處,然後中斷並返回,當函式下次執行時會由此繼續執行:
def
fib(num):
i=0a,b=0,1
while(iyield b #中斷點
tmp=a+b
a=bb=tmp
i+=1
g=fib(10)
for i in range(4):
print(g.__next__())
print("優先順序更高的任務。。。")
for i in range(4):
print(g.__next__())
函式生成器的好處是自帶中斷效果,能隨時暫停隨時進入。
函式生成器中有乙個.send()方法,它會向指定生成器的yield傳送乙個值並喚醒那個生成器:
def
consumer
(): print("consumer is ready...")
while
true:
production=yield
#消費者會在此中斷
print("production{} is used.".format(production))
defproducer
(consumer):
print("producer is ready...")
for i in range(5):
print("producing...")
consumer.send(i) #將i傳送給c的yield並喚醒c
c=consumer()
c.__next__()
producer(c)
此段**建議使用斷點觀察程式的執行順序。
iterator物件表示的是乙個資料流,iterator物件可以被next()函式呼叫並不斷返回下乙個資料,直到沒有資料時丟擲stopiteration錯誤。可以把這個資料流看做是乙個有序序列,但我們卻不能提前知道序列的長度,只能不斷通過next()函式實現按需計算下乙個資料,所以iterator的計算是惰性的,只有在需要返回下乙個資料時它才會計算。
iterator甚至可以表示乙個無限大的資料流,例如全體自然數。而使用list是永遠不可能儲存全體自然數的。
參考鏈結
Python學習筆記 生成器
有時候乙個列表裡的元素過多,多到計算機記憶體存不下來,我們就需要想乙個辦法解決這個問題,如果能在需要的時候生成新元素就好了,可以用生成器。生成器 一種邊迴圈邊根據某種演算法計算生成元素的機制 如何建立乙個生成器呢,最簡單的方法通過修改一下列表生成器建立。n n for n in range 10 d...
Python生成器學習筆記
生成器在python中首先是乙個物件,用於建立python序列。使用生成器可以迭代龐大的序列,且不需要在記憶體中建立和儲存整個序列。通常,生成器是為迭代器產生資料的。典型的使用用例是range 函式。每次迭代生成器時,生成器會記住上一次呼叫的內容,並且返回下乙個值。生成器函式和普通函式類似,但是它的...
Python筆記 生成器
日期 20170925 python中有乙個很有趣的東東,叫生成器。我們先來看看簡單的 1,usr bin python3 defmygenerator for n in range 1,4 yield n return done print mygenerator print num mygene...