Python基礎 函式的迭代器和生成器

2022-08-23 18:21:11 字數 1635 閱讀 5507

魔性面試題1解析:

def add(n,i):

return n+i

def test():

for i in range(4):

yield i

g=test()

for n in [1,10]:

g=(add(n,i) for i in g)

print(n)

print(list(g))

10[20, 21, 22, 23]

上面**的執行順序是這樣的:從上到下:

第乙個函式add就是實現了乙個簡單的加法運算

第二個函式test是乙個生成器函式,如果呼叫它會返回乙個生成器

g=test(),這一行呼叫了生成器函式,所以此刻g就是乙個生成器(它的本質還是迭代器)

然後執行for迴圈,這裡迷惑人的就是這個for迴圈,為了減少它的魔性,我們把for迴圈拆開來看:

當n = 1時:

執行了:g=(add(n,i) for i in g)

當n = 10時:

執行了:g=(add(n,i) for i in g)

乍一看這兩行**還是有點迷糊,但是我們要知道,生成器有個最大的特性就是惰性,當你不進行迭代時它就不進行運算,想要對生成器進行迭代有以下幾種方法:

第一種:for迴圈,for迴圈的本質就是呼叫了iter和next方法進行了迭代

第二種:呼叫next方法

第三種:呼叫send方法

第四種:資料型別強制轉換,比如使用list()強制轉換。

只要沒有以上四種方法進行迭代,那麼生成器就沒有進行運算,所以在上面的for迴圈中無論是n=1時還是n=10時,生成器 g 都沒有參與運算,

當n = 1時,g=(add(n,i) for i in g),這個表示式的結果g 就是乙個表示式,沒有進行運算,g的值就是乙個表示式(add(n,i) for i in g),括號裡面的g實際上是test(),所以g = (add(n,i) for i in test()),僅此而已

當n = 10時,g=(add(n,i) for i in g),把n=1時的g的結果帶入進去就是g=(add(n,i) for i in (add(n,i) for i in test()))

當整段**執行到print(list(g))語句之前,g的值就是一段**,或者你可以稱之為演算法,沒有進行任何運算,裡面的n就是n,g就是g

不過此時因為**是按照流程執行的,並且for迴圈已經執行完畢,所以n的值等於10

當執行print(list(g))語句時,生成器才開始輸出資料,此時執行最後乙個g的賦值語句:

g=(add(n,i) for i in (add(n,i) for i in test()))

這時 n 的值等於10(因為**是按照流程執行的,for迴圈已經執行完了,n的最終結果就是10),其中後面的(add(n,i) for i in test())這段**的結果依然是個生成器,迭代後應為[10,11,12,13],所以最終的結果可以理解成:(add(n,i) for i in [10,11,12,13]),所以最終結果為:20,21,22,23

等待更新……………………

後面再寫

python基礎 22 函式 迭代器

我們已經知道,可以直接作用於for迴圈的資料型別有以下幾種 一類是集合資料型別,如list tuple dict set str等 一類是generator,包括生成器和帶yield的generator function。這些可以直接作用於for迴圈的物件統稱為可迭代物件 iterable,可迭代的...

Python基礎 迭代器

二 生成器 三 推導表示式 迭代器就是乙個容器,將可迭代物件通過iter包起來 li 1 2,3 4,5 a liter li 迭代器print next a 1print next a 2print next a 3 乙個個取值 1.訪問者不需要去關心內部結構,只需要通過next不斷去取下乙個內容...

Python基礎 迭代器

可以直接作用於for迴圈的資料型別有一下幾種 一類是集合資料型別 如list tuple dict set str等 一類是generator,包括生成器和帶yield的generator function 這些可以直接作用與for迴圈的物件統稱為可迭代物件 iterable 可以使用isinsta...