python 迭代器、生成器

一、迭代器協議

對象必須提供一個next方法,執行該方法要麼返回迭代中的下一項,要麼就引起一個Stoplteration 異常,終止迭代(只能往後不能往前退)。

二、for循環提高

for循環中,調用對象__iter__()方法,將其變成遵循迭代器協議的迭代對象,再通過其內部的__next__()方法進行依次訪問,從而達到遍歷效果。

三、生成器

可以理解爲數據類型,這種數據類型自動實現了迭代器協議(其他數據類型需要調用自己內置的__iter__方法),生成器就是可迭代對象。

運行生成器方法:

  1. 生成器函數  __next__()
  2. python自帶方法:next(生成器)
  3. .send(參數):生成器函數.send(參數),send中的參數會傳入到當前停止 yield 中。

生成器表現形式:(generatorobject 生成器對象)

  1. 生成器函數:與常規函數定義相同,但是使用yield返回結果,在每個結果中間掛起函數,以使下次從它離開的地方繼續執行。
  2. 生成器表達式:類似於列表推導,但是生成器按需產生結果的一個對象,而不是一次構建一個結果列表。
L = [x + 1 for x in range(10)]
print(L)

# 輸出:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

基本語法:

def 函數名():
    yield 返回值
    yield 返回值

# yield 特性:與return相同,可以yield多次,可以保存狀態。

yield 語句是生成器中的關鍵語句,生成器在實例化時並不會被執行,而是等待調用其__next__()方法纔開始運行。並且當程序運行完yield語句後就會“吼(hold)住”,即保持當前狀態且停止運行,等待下一次遍歷時才恢復運行,並會把 .send(參數) 中的參數傳回到yield。

生成器案例:生產者、消費者模型(吃包子案例)

# 吃包子
def conSumer(name):
    print('我是[%s],準備開始吃包子了!' % name)
    while True:
        baozi = yield
        print('%s 很開心的把 [%s] 吃掉了。' % (name,baozi))


# 生成包子
def producer():
    c1 = conSumer('tt')
    c1.__next__()
    for i in range(10):
        c1.send('包子%s' % i)


producer()

執行結果:

我是[tt],準備開始吃包子了!
tt 很開心的把 [包子0] 吃掉了。
tt 很開心的把 [包子1] 吃掉了。
tt 很開心的把 [包子2] 吃掉了。
tt 很開心的把 [包子3] 吃掉了。
tt 很開心的把 [包子4] 吃掉了。
tt 很開心的把 [包子5] 吃掉了。
tt 很開心的把 [包子6] 吃掉了。
tt 很開心的把 [包子7] 吃掉了。
tt 很開心的把 [包子8] 吃掉了。
tt 很開心的把 [包子9] 吃掉了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章