記一道有意思的python列表推斷式

2021-09-18 01:49:52 字數 2655 閱讀 1372

result = [lambda x: x + i for i in range(10)]

print(result[0](10))

乍一看這**似乎也就那樣,再一看哦似乎是有點東西,仔細一看,這道題不簡單!

它結合了以下知識點

看乙個例子

a = 10

def test():

a += 1

print(a)

test()

python的規則是,如果在函式內部要修改乙個變數,那麼這個變數需要是內部變數,除非你用global宣告了它是外部變數。很明顯,我們沒有在函式內部定義變數a,所以會彈出區域性變數在未定義之前就引用的錯誤。

看乙個例子

​​​>>> result = [x+x for x in range(1,10)]

>>> result

[2, 4, 6, 8, 10, 12, 14, 16, 18]

列表推導式要這麼理解,首先執行for迴圈,對於每乙個x,代入x*x中進行運算,將運算結果逐一新增到乙個新列表內,迴圈結束,得到最終列表。它相當於下面的**:

​>>> result = 

>>> for i in range(1, 10):

>>> print(result)

[2, 4, 6, 8, 10, 12, 14, 16, 18]

看乙個例子

​>>> result = lambda a,b:a+b

>>> print(result)

at 0x0000024bab54e400>

>>> res = result(0,10)

>>> print(res)

10

匿名函式只能有乙個表示式,不用也不能寫return語句,表示式的結果就是其返回值。 匿名函式沒有函式名字,不必擔心函式名衝突,節省字義空間。匿名函式也是乙個函式物件,也可以把匿名函式賦值給乙個變數,再利用變數來呼叫該函式。只有呼叫這個匿名函式,它才會執行冒號後面的**,這也是函式的執行法則,只有被呼叫時,函式內部的命名空間才會生效,在被呼叫之前它就是乙個函式名指向的記憶體位址而已。它相當於下面的**

>>> def result(a,b):

return a+b

>>> result(0,10)

10

根據上面的分析現在可以將上面的列表推斷式

​lis = 

for i in range(10):

res = lambda x:i+x

當前函式引用到上一層函式的區域性命名空間的變數時就會觸發閉包規則。我們說觸發了閉包的函式叫做閉包函式,但是要注意一點:只有當呼叫閉包函式的時候它才會去引用外層函式的變數,因為在呼叫閉包函式之前,閉包內部的命名空間還不存在。

匿名函式lambda x:i+x引用了外層函式的命名空間內的變數i,所以它觸發了閉包規則,然後外層函式的返回值是乙個列表,這個列表的元素為十個閉包函式名指向的記憶體位址,雖然for i in range(10)這段**裡面的i的值分別被賦予了十個值,但是閉包函式res並沒有引用這十個值,因為閉包函式此時此刻還沒有被真正呼叫,列表推導式僅僅是把十個匿名函式指向的記憶體位址儲存在了乙個列表裡,因為沒有呼叫,所以匿名函式內部的**並沒有執行,也就不存在引用。

所以外部函式的返回值就是這樣的乙個列表:[lambda x:i+x,lambda x:i+x,.....]它相當於下面的**

def waibu():

lis =

for i in range(10):

def bibao(i):

return x + i

return lis

print(result[0](10)),這條語句到底是幹嘛的呢?其實它幹的事情只有乙個,那就是遍歷了waibu函式()返回的列表

注意:此時此刻匿名函式才真正被呼叫了,然後它會引用外層命名空間的變數

把這個列表推導式拆開的話 它應該是下面這個樣子,結果完全一樣:

​​def waibu():

lis =

for i in range(10):

def bibao(x):

return i + x

return lis

result = waibu()

print(result[2](10))​​

其實還等價於

def multipliers():

squares =

for i in range(10):

res = lambda x:i+x

return squares

squares2 =

for m in multipliers():

print(squares2)

一道很有意思的題目

先列出 然後再開始解析 include stdafx.h include using namespace std class a class b public a void seta a data,int idx int tmain int argc,tchar argv for int i 0 i...

一道有意思的邏輯題

在一條街上,有5座房子,噴了5中顏色。每個房子住著不同國籍的人。每個人喝不同的飲料,抽不同品牌的香菸,養不同的寵物。問題是 誰養魚?30分 2.瑞典人養狗 3.丹麥人喝茶 4.綠色房子在白色房子左邊 5.綠房子主人喝咖啡 6.抽pallmall香菸的人養鳥 7.黃色房子的主人抽dunhill香菸 8...

一道有意思的機試題

一道有意思的機試題 有四個學生 六門課程,要求使用三個頁面,第乙個頁面出現四個學生的選擇,選擇了學生後,到第二個頁面出現選擇了學生的列表,每個學生後面都有六門課程供學生選擇,選好課程後,到第三個頁面出現選擇了的學生和對應的課程列表。乍一看很簡單的一道題,不過我也用了乙個小時左右的時間,最快的乙個!題...