Python 生成器(generator)解析

引入,玩過Python的可能都聽說過生成器,帶yield關鍵字的函數返回的就是生成器。生成器又有什麼作用呢?

   斐波那契數列 

    斐波那契數列是一個遞歸數列,他的特徵就是前兩個書相加等於後一個數(除了最前面的兩個數)1,1,2,3

    ,5

       看到這裏我們可能會想到我們平時最常規的一種實現方式:

def creat_fibonacci():
    a, b = 1, 0
    for x in range(10):
        print(b)
        a, b = b, a + b

這裏通過調用creat_fibonacci()方法打印出想要的數列。這裏我們可能會想到利用率不是太高,只是遍歷,我們怎麼可以把他存在一個地方,想用的時候再去調用。

 我們可以將其存入list列表中,在使用的時候在遍歷這個列表:

def creat_fibonacci():
    a, b = 1, 0
    lists = []
    count = 0
    for x in range(10):
        lists.append(b)
        # print(b)
        a, b = b, a + b
        count += 1
    return lists


list1 = creat_fibonacci()
for x in list1:
    print(x)

通過這種方式調用時可以更加靈活的使用list列表,但是出現的問題是可能佔用的內存空間會比較大,如果生成一萬數一百萬個呢?可能需要的內存空間就比較大。

從這裏我們就開始介紹今天的主角!!!yield

該如何使用呢?這裏我先貼一段代碼例子

def creat_fibonacci():
    a, b = 1, 0
    for x in range(10):
        yield b
        a, b = b, a + b

for x in creat_fibonacci():
    print(x)

這裏調用方法時候返回的是一個生成器對象(generator),通過遍歷生成器對象,打印數列,這裏重點說的是yield的作用,

當我們將返回的生成器對象通過next(gennrator)一次一次遍歷的時候,只返回一個數,這裏返回的就是 yield 後面跟的屬性值,而當你在此執行next方法時,他會再次遍歷,再次遍歷的是接着上次返回時候的地方開始執行。

# 第一種遍歷
num = creat_fibonacci()
count = next(num)
print(count)
# 第二種遍歷
num2 = num.__next__()
print(num2)

這兩種方式都能遍歷出生成器對象。

總結:

    yield 的作用就是把一個函數變成一個 generator,帶有 yield 的函數不再是一個普通函數,Python 解釋器會將其視爲一個 generator,調用 creat_fibonacci() 不會執行 creat_fibonacci 函數,而是返回一個 iterable 對象!在 for 循環執行時,每次循環都會執行 creat_fibonacci函數內部的代碼,執行到 yield b 時,creat_fibonacci函數就返回一個迭代值,下次迭代時,代碼從 yield b 的下一條語句繼續執行,而函數的本地變量看起來和上次中斷執行前是完全一樣的,於是函數繼續執行,直到再次遇到 yield。

Send 的作用

這裏還有一個方法send,send的方法時可以對yield位置賦值:

def creat_fibonacci():
    count = 0
    while count < 5:
        test = yield count
        print(test)
        count += 1


num = creat_fibonacci()
num.send("hhh")

send方法的作用就是,在每次執行到yield位置時候,返回yield位置的值,當我們再次調用時,代碼中test的值是空的,應爲不會再將返回的值記錄起來賦值給test,這時候我們可以使用send()方法,給上次返回的地方賦值,這裏就是講“hhh”字符串賦值給text,這裏next(num)作用同num.send(None)第一次使用時候需要傳入None,因爲第一調用沒有地方賦值,或者調用一次next

判斷是否是生成器

    判斷要遍歷的對象是否是生成器,可以通過generatorfuncton(),方法判斷調用的對象是否是生成器對象,判斷是否需要遍歷。

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