全文都是抄來的html
Python中的lambda的「一個語法,三個特性,四個用法,一個爭論」。python
在Python中,lambda的語法是惟一的。其形式以下:web
其中,lambda是Python預留的關鍵字,argument_list和expression由用戶自定義。具體介紹以下。express
這裏的expression是一個關於參數的表達式。表達式中出現的參數須要在argument_list中有定義,而且表達式只能是單行的。如下都是合法的表達式:編程
這裏的 lambda argument_list: expression
表示的是一個函數。這個函數叫作lambda函數。api
lambda函數有以下特性:閉包
下面是一些lambda函數示例:app
因爲lambda語法是固定的,其本質上只有一種用法,那就是定義一個lambda函數。在實際中,根據這個lambda函數應用場景的不一樣,能夠將lambda函數的用法擴展爲如下幾種:函數
將lambda函數賦值給一個變量,經過這個變量間接調用該lambda函數。學習
將lambda函數賦值給其餘函數,從而將其餘函數用該lambda函數替換。
將lambda函數做爲其餘函數的返回值,返回給調用者。
舉個栗子
優勢1,2 就不說了,很容易理解,關於第三個,例如當在一個類中實現的方法不多時,或者僅有一個方法時,就能夠選擇使用閉包。
舉個栗子
閉包的概念差很少就是這樣了。
上述式子的輸出結果: 預計結果爲:0, 2, 4, 6 實際輸出爲:3, 3, 3, 3
lambda x: x*i
爲內層(嵌)函數,他的命名空間中只有 {'x': 1} 沒有 i , 因此運行時會向外層函數(這兒是列表解析式函數 [ ])的命名空間中請求 i 而當列表解析式運行時,列表解析式命名空間中的 i 通過循環依次變化爲 0-->1-->2-->3 最後固定爲 3 , 因此當 lambda x: x*i
內層函數運行時,去外層函數取 i 每次都只能取到 3lambda x: x*i
增長參數,命名空間中有了用來存儲每次的 i , 即改爲 [lambda x, i=i: x*i for i in range(4)]
這樣每一次,內部循環生成一個lambda 函數時, 都會把 --i--做爲默認參數傳入lambda的命名空間 循環4次實際lambda表達式爲: 第一次:lambda x, i=0 第二次:lambda x, i=1 第三次:lambda x, i=2 第四次:lambda x, i=3
函數fun = [lambda x: x*i for i in range(4)]
等價於:以下函數
查看該函數命名空間及 I 值變化:
#運行結果爲:爲了排版美觀,我已將輸出lambda_函數地址更名爲:lam函數1 2 3
能夠看見:就像上面所說的:四次循環中外層函數命名空間中的 i 從 0-->1-->2-->3 最後固定爲3, 而在此過程當中內嵌函數-Lambda函數中由於沒有定義 i 因此只有Lambda 函數動態運行時, 在本身命名空間中找不到 i 纔去外層函數複製 i = 3 過來,結果就是全部lambda函數的 i 都爲 3, 致使得不到預計輸出結果:0,1,2,3 只能獲得 3, 3, 3, 3
給內層函數 lambda增長默認參數,命名空間中有了用來存儲每次的 i , 即改爲 `def lambda(x, i=i) :` 這樣每一次, 內部循環生成一個lambda 函數時,都會把 i 做爲默認參數傳入lambda的命名空間 循環4次實際lambda表達式爲: 第一次:lambda( x, i=0) 第二次:lambda(x, i=1) 第三次:lambda(x, i=2) 第四次:lambda(x, i=3)
這樣咱們就能獲得預計的結果:0, 1, 2, 3
只有函數、類、模塊會產生做用域,代碼塊不會產生做用域。做用域按照變量的定義位置能夠劃分爲4類:
python解釋器查找變量時,會按照順序依次查找局部做用域--->嵌套做用域--->全局做用域--->內建做用域,在任意一個做用域中找到變量則中止查找,全部做用域查找完成沒有找到對應的變量,則拋出 NameError: name 'xxxx' is not defined的異常。
人生還有意義。那必定是還在找存在的理由