生成器詳解

2022-01-20 15:00:04 字數 4366 閱讀 4779

什麼是生成器

生成器是一種特殊的迭代器,生成器實現了迭代器協議__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,執行後返回...