python這麼優雅的語言,我也是醉了......
事情由一段**引發,請看:
上述的列表推導式+lambda表示式+for迴圈,他們碰撞出來的結果搞的人暈頭轉向,咱們逐步來分析一下他們到底是個什麼鬼。
lambda表示式可以表示成:
def func(x):
return x*i
加上for迴圈:
for i in range(10):
def func(x):
return x*i
加上列表推導式: # 注釋一
li =
def funcs():
for i in range(10):
def func(x):
return x*i
return li
funcs()
到此,就可以看清楚他的結構了,funcs函式裡面形成了乙個
閉包閉包的兩個特性:
①、內部函式使用外部函式的變數(不對外部函式的變數進行重新賦值)
②、外部函式 return 內部函式的函式名(其實是返回內部函式的記憶體位址)
對上面的函式進行簡化:去掉for迴圈,使用單個變數代替,去掉 列表 li 直接返回內部函式名,它就變成了下面這個樣子
def funcs():
i=9 # 定義了變數,也稱為內部函式的環境變數,它不會改變,不被外界影響
def func(x):
return x*i # 使用了外部函式的變數
return func # 返回了內部函式
簡單理解:閉包 = 內部函式 + 環境變數
閉包的特性:當內部函式返回的時候,會把連同內部函式定義時候的環境變數一同返回
了解了閉包,在來看結果為什麼全都是18,而不是預期結果:
①區分內部函式的定義和呼叫:
當我們只到是定義了外部和內部函式,呼叫了外部函式,並未呼叫內部函式,也就是到注釋一
for迴圈的作用就是建立10個函式,最後i 的取值是9
所以我們獲得了類似下面的圖譜:
當我們進行內部函式呼叫的時候,此時的情形是:
有乙個包含10個函式的列表,變數 i=9
再加上閉包的特性,i 會隨著內部函式的一同返回,所以呼叫依次內部函式的時候,情形就成了下面這樣:以呼叫第1個函式為例
所以結果就成了 2 * 9 = 18
再呼叫別的內部函式都是如此邏輯。
知乎中此問題的回答者 @op小劍 提到了延遲繫結
li =
def funcs():
for i in range(10):
def func(x, i=i): # 給內部函式傳參, i 是內部函式的區域性變數,當所有內部函式定義完畢,i 的值也變成了乙個列表(range(10))
return x*i # 呼叫的時候其實是呼叫的內部函式的值
return li
for func in funcs():
func(2)
修改到列表推導式+lambda表示式就是下面的情況:
funcs = [lambda x, i=i: x*i for i in range(10)]
for func in funcs:
print(func(2))
此時呼叫的情形就像下面的圖譜:
最後分享乙個python的執行過程展示**,希望可以給大家帶來幫助
lambda表示式的推導
學習多執行緒過程中解除到lambda表示式,現在總結一下。為什麼使用lambda表示式 函式式介面 任何介面,如果只包含乙個抽象方法,那麼它就是乙個函式式介面直接上 感受各種類 package com.laoongcai.gitxuexi.lambda author chen description...
python列表推導式和lambda表示式
列表推導式簡單明瞭,但要注意if條件的位置。if寫在前面 c i if i 2 0 else 1for i in a 遍歷a的每個元素,如果i為偶數直接返回,否則直接返回1。此處if寫在for前面要求必須有else項 a 1,2,3 c i if i 2 0 else 1for i in a c 1...
lambda表示式推導和使用
params expression params statement params new thread system.out.println 多執行緒學習。start 1 lambda表示式逐級推導 1 package com.sxt.thread 23 4 lambda表示式 簡化執行緒 用一次...