摘要:這是一道魔性面試題,難倒了無數(shù)英雄好漢上面代碼的執(zhí)行順序是這樣的從上到下第一個(gè)函數(shù)就是實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的加法運(yùn)算第二個(gè)函數(shù)是一個(gè)生成器函數(shù),如果調(diào)用它會(huì)返回一個(gè)生成器這一行調(diào)用了生成器函數(shù),所以此刻就是一個(gè)生成器它的本質(zhì)還是迭代器然后執(zhí)行循環(huán)
這是一道魔性面試題,難倒了無數(shù)英雄好漢……
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]上面代碼的執(zhí)行順序是這樣的:從上到下:
第一個(gè)函數(shù)add就是實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的加法運(yùn)算 第二個(gè)函數(shù)test是一個(gè)生成器函數(shù),如果調(diào)用它會(huì)返回一個(gè)生成器 g=test(),這一行調(diào)用了生成器函數(shù),所以此刻g就是一個(gè)生成器(它的本質(zhì)還是迭代器) 然后執(zhí)行for循環(huán),這里迷惑人的就是這個(gè)for循環(huán),為了減少它的魔性,我們把for循環(huán)拆開來看: 當(dāng)n = 1時(shí): 執(zhí)行了:g=(add(n,i) for i in g) 當(dāng)n = 10時(shí): 執(zhí)行了:g=(add(n,i) for i in g)
乍一看這兩行代碼還是有點(diǎn)迷糊,但是我們要知道,生成器有個(gè)最大的特性就是惰性,當(dāng)你不進(jìn)行迭代時(shí)它就不進(jìn)行運(yùn)算,想要對(duì)生成器進(jìn)行迭代有以下幾種方法:
第一種:for循環(huán),for循環(huán)的本質(zhì)就是調(diào)用了iter和next方法進(jìn)行了迭代
第二種:調(diào)用next方法
第三種:調(diào)用send方法
第四種:數(shù)據(jù)類型強(qiáng)制轉(zhuǎn)換,比如使用list()強(qiáng)制轉(zhuǎn)換。
只要沒有以上四種方法進(jìn)行迭代,那么生成器就沒有進(jìn)行運(yùn)算,所以在上面的for循環(huán)中無論是n=1時(shí)還是n=10時(shí),生成器 g 都沒有參與運(yùn)算,
當(dāng)n = 1時(shí),g=(add(n,i) for i in g),這個(gè)表達(dá)式的結(jié)果g 就是一個(gè)表達(dá)式,沒有進(jìn)行運(yùn)算,g的值就是一個(gè)表達(dá)式(add(n,i) for i in g),括號(hào)里面的g實(shí)際上是test(),所以g = (add(n,i) for i in test()),僅此而已
當(dāng)n = 10時(shí),g=(add(n,i) for i in g),把n=1時(shí)的g的結(jié)果帶入進(jìn)去就是g=(add(n,i) for i in (add(n,i) for i in test()))
當(dāng)整段代碼執(zhí)行到print(list(g))語句之前,g的值就是一段代碼,或者你可以稱之為算法,沒有進(jìn)行任何運(yùn)算,里面的n就是n,g就是g
不過此時(shí)因?yàn)榇a是按照流程執(zhí)行的,并且for循環(huán)已經(jīng)執(zhí)行完畢,所以n的值等于10
當(dāng)執(zhí)行print(list(g))語句時(shí),生成器才開始輸出數(shù)據(jù),此時(shí)執(zhí)行最后一個(gè)g的賦值語句:
g=(add(n,i) for i in (add(n,i) for i in test()))
這時(shí) n 的值等于10(因?yàn)榇a是按照流程執(zhí)行的,for循環(huán)已經(jīng)執(zhí)行完了,n的最終結(jié)果就是10),其中后面的(add(n,i) for i in test())這段代碼的結(jié)果依然是個(gè)生成器,迭代后應(yīng)為[10,11,12,13],所以最終的結(jié)果可以理解成:(add(n,i) for i in [10,11,12,13]),所以最終結(jié)果為:20,21,22,23
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/42559.html
摘要:到這里,如果你明白了,我們就可以繼續(xù)進(jìn)行下一步了理解匿名函數(shù)。 似乎只要一沾上for循環(huán),難度立刻加倍,下面我們來看一道python的面試題: 要求寫出下面代碼的輸出結(jié)果并且解釋原因。 def multipliers(): return [lambda x:i*x for i in range(4)] print([m(2) for m in multipliers()]) 這...
摘要:昨天晚上,筆者有幸參加了一場(chǎng)面試,有一個(gè)環(huán)節(jié)就是現(xiàn)場(chǎng)編程題目如下示例數(shù)據(jù)如下,求每名學(xué)生對(duì)應(yīng)的成績(jī)最高的那門科目與,用實(shí)現(xiàn)這個(gè)題目看上去很簡(jiǎn)單,其實(shí),并不簡(jiǎn)單。 ??昨天晚上,筆者有幸參加了一場(chǎng)面試,有一個(gè)環(huán)節(jié)就是現(xiàn)場(chǎng)編程!題目如下:??示例數(shù)據(jù)如下,求每名學(xué)生(ID)對(duì)應(yīng)的成績(jī)(score)最高的那門科目(class)與ID,用Python實(shí)現(xiàn): showImg(https://se...
摘要:閉包正確的說應(yīng)該是指一個(gè)閉包域每當(dāng)聲明了一個(gè)函數(shù)它就產(chǎn)生了一個(gè)閉包域可以解釋為每個(gè)函數(shù)都有自己的函數(shù)棧每個(gè)閉包域?qū)ο蠖加幸粋€(gè)不是屬性內(nèi)默認(rèn)有個(gè)名為的全局引用有了這個(gè)引用就可以直接調(diào)用的屬性或方法凡是在閉包域內(nèi)聲明的變量或方法外部無法直接訪問 閉包 正確的說,應(yīng)該是指一個(gè)閉包域,每當(dāng)聲明了一個(gè)函數(shù),它就產(chǎn)生了一個(gè)閉包域(可以解釋為每個(gè)函數(shù)都有自己的函數(shù)棧),每個(gè)閉包域(Function...
摘要:所以能用的地方盡量用,相等運(yùn)算符隱藏的類型轉(zhuǎn)換,會(huì)帶來一些違反直覺的結(jié)果。 這是在國(guó)外的一道面試題看到的,大家先自己想一下,在什么情況下這個(gè)判斷會(huì)成立?按正常思維想,這個(gè)是不可能成立的,但nothing is impossible,首先貼上正確答案代碼 const a = { i: 1, toString: function () { return a.i++; }...
摘要:這是我在一次面試中,被面試官所提問的一道題在這次面試題中相等指的是對(duì)象的屬性個(gè)數(shù)值相等有這樣兩個(gè)李德華張德華我能想到的一種方案解答過程的思考由于沒有,我只能通過轉(zhuǎn)化成數(shù)組進(jìn)入第二步,對(duì)象中的屬性在另一個(gè)中是否存在。 這是我在一次面試中,被面試官所提問的一道題 在這次面試題中 相等:指的是對(duì)象的屬性個(gè)數(shù)值相等 有這樣兩個(gè)obj let obj1 = { name:李德華, ...
閱讀 3770·2021-10-13 09:39
閱讀 3813·2021-09-24 09:48
閱讀 1207·2021-09-01 10:30
閱讀 2538·2019-08-30 15:55
閱讀 1788·2019-08-29 16:39
閱讀 2307·2019-08-26 13:55
閱讀 3063·2019-08-26 12:23
閱讀 1645·2019-08-26 11:59