什麼是生成器
生成器是一種特殊的迭代器,生成器實現了迭代器協議__iter__(),__next__()
生成器解決什麼問題
如果有一億的資料要我們處理,我們通過列表的方式來訪問的話,這一億的資料是存放在記憶體的,這樣會非常的消耗記憶體的,但是如果我們使用生成器的話,每當處理乙個資料的時候,記憶體中只是相當於存了乙個資料,這樣可以節省大量的記憶體
簡單案例
當生成器物件__next__()
的時候,生成器函式會執行到下乙個yield,並會返回乙個引數
例一
def zx():
yield 1
print(1)
if __name__ == '__main__':
zx=zx()
data=zx.__next__()
print(data)
1
例二
觸發stopiteration異常的兩種方式
1.迭代完最後乙個元素後,觸發stopiteration異常
def zx():
yield 1
print(1)
if __name__ == '__main__':
zx=zx()
data=zx.__next__()
data=zx.__next__()
1
traceback (most recent call last):
file "c:/users/administrator/desktop/01python/研究/生成器/t1.py", line 8, in data=zx.__next__()
stopiteration
2.執行生成器函式的時候遇到return,return的值,會成為異常的說明值,如例子的2
def zx():
yield 1
return 2
print(1)
yield 3
if __name__ == '__main__':
zx=zx()
data=zx.__next__()
data=zx.__next__()
traceback (most recent call last):
file "c:/users/administrator/desktop/01python/研究/生成器/t1.py", line 10, in data=zx.__next__()
stopiteration: 2
迭代器物件和生成器的產生區別
迭代器物件是通過可迭代物件的__iter__()
生成的
zx=[1,2,3,4,5,6,7,8,9]
z1=zx.__iter__()
生成器的建立方式類似生成物件的方式
def zx():
for i in range(10):
yield i
z1=zx()
send方法
協程的實現主要就是靠的生成器的send方法
例子1-錯誤使用
def dog():
print('小烏')
while true:
food = yield
if food == '骨頭':
yield '好吃'
else:
yield '旺旺旺'
xw = dog() #只是用於返回乙個生成器物件,函式並不會執行下去
print(xw.send('骨頭'))
出現錯誤,不能給剛建立的生成器傳送非空的值
traceback (most recent call last):
file "c:/users/administrator/desktop/01python/研究/生成器/t5_send.py", line 10, in print(xw.send('骨頭'))
typeerror: can't send non-none value to a just-started generator
報錯資訊說不能傳送非空的值,那我們來試試傳送乙個none會發生什麼
print(xw.send(none))
執行成功了
小烏
none
其實也可以用__next__()
也能做到這個列印結果
print(xw.__next__())
結果一樣
小烏
none
結論
1.__next__()
的效果其實和send(none)一樣
2.yield預設返回none
例子2-正確使用
def dog():
print('小烏')
while true:
food = yield
if food == '骨頭':
yield '好吃'
else:
yield '旺旺旺'
xw = dog() #只是用於返回乙個生成器物件,函式並不會執行下去
print(xw.__next__())
print(xw.send('骨頭'))
結果
小烏
none
好吃
結論
1.當生成器剛建立完成,第一次使用先next或者send(none),不能直接send(非空引數)
2.send()有給yield的賦值功能
總結1.__next__()
的效果其實和send(none)一樣
2.當生成器剛建立完成,第一次使用先next或者send(none),不能直接send(非空引數)
3.send()方法就相當於__next__()
和賦值功能的結合
計數器
def jishu():
i = 0
while true:
zx = yield i
if zx == "按一下":
i+=1
elif zx == "重置":
i=0js=jishu()
print(js.__next__())
print(js.send("按一下"))
print(js.send("按一下"))
print(js.send("按一下"))
print(js.send("按一下"))
print(js.send("重置"))
print(js.send("按一下"))
print(js.send("按一下"))
0 初始化
1 按一下23
40 重置
12
協程
吃包子
def consumer(name):
print(f"老闆上包子")
while true:
baozi = yield
print(f":吃了")
def producer():
for i in range(2):
print('廚師做了兩個包子')
c1.send(f"肉包")
c2.send(f"菜包")
c1 = consumer("小黃")
c2 = consumer("小烏")
c1.__next__()
c2.__next__()
producer()
小黃老闆上包子
小烏老闆上包子
廚師做了兩個包子
小黃:吃了肉包0
小烏:吃了菜包0
廚師做了兩個包子
小黃:吃了肉包1
小烏:吃了菜包1
斐波那契數列def zx(n):
z,x=0,1
while x < n:
yield x
z,x = x,z+x
z=zx(10)
for i in z:
print(i)
python生成器詳解
usr bin python coding utf8 生成器函式 只要函式體包含yield關鍵字 name該函式就是生成器函式 def foo print first yield 1 print second yield 2 print third yield 3 g foo print g pri...
awk(報告生成器)詳解
awk是乙個強大的文字分析工具,相對於grep的查詢,sed的編輯,awk在其對資料分析並生成報告時,顯得尤為強大。簡單來說awk就是把檔案逐行的讀入,以空格為預設分隔符將每行切片,切開的部分再進行各種分析處理。awk a.k.a.aho,kernighan and weinberger awk的三...
python 生成器作用 Python生成器
生成器介紹 在函式內部包含yield關鍵字,那麼該函式執行的結果是生成器,生成器就是迭代器。生成器的功能 把函式結果做成迭代器 以一種優雅的方式封裝好iter,next 提供了一種自己定義迭代器的方式。使用生成器建立乙個迭代器 def a print a yield 11 使用yield,執行後返回...