lambda
匿名函數
匿名函數,顧名思義就是不需要具體定義函數名的函數。我們首先拋開復雜的定義,看兩個具體例子。
先看一個無參數函數的例子。假設我們需要一個return 1
的函數,如果使用普通的函數定義方式,其代碼為:
# 使用def關鍵字進行函數定義
def get_one():return 1# 輸出1
print(get_one())
如果我們使用lambda
匿名函數,我們則不需要使用def
關鍵字而改用lambda
關鍵字,其代碼為:
# 使用lambda匿名函數進行函數定義
# 注意這里的get_one_lambda看似是一個變量名
# 但實際上是一個函數名
get_one_lambda = lambda: 1print(get_one_lambda)
# 輸出形如 <function <lambda> at 0x00000249F7AD7B00> 的結果
# 這一長串復雜的十六進制數是函數get_one_lambda的內存地址print(get_one_lambda())
# 在函數名get_one_lambda后面加上括號,才能正確地輸出1
把上述代碼進行合并操作,可以無需聲明函數名get_one_lambda
,直接得到結果:
# 這里的(lambda: 1)等價于上面的函數名get_one_lambda
# (lambda: 1)()等價于get_one_lambda()
# 顯然get_one_lambda這個函數名是不必要的,故稱之為"lambda匿名函數"print(lambda: 1)
# 輸出形如 <function <lambda> at 0x00000249F7AD7B00> 的結果
# 這一長串復雜的十六進制數是該匿名函數的內存地址print((lambda: 1)())
# 在匿名函數后面加上括號,才能正確地輸出1
再看一個有參數函數的例子。假設我們需要一個計算兩個參數x
和y
相加return x+y
的函數,如果使用普通的函數定義方式,其代碼為:
# 使用def關鍵字進行函數定義
def add(x, y):return x+y# 輸出30
print(add(10, 20))
如果我們使用lambda
匿名函數,我們則不需要使用def
關鍵字而改用lambda
關鍵字,其代碼為:
# 使用lambda匿名函數進行函數定義
# 注意這里的get_one_lambda看似是一個變量名
# 但實際上是一個函數名
add_lambda = lambda x,y: x+yprint(add_lambda)
# 輸出形如 <function <lambda> at 0x00000249F7AD7B00> 的結果
# 這一長串復雜的十六進制數是函數add_lambda的內存地址print(add_lambda(10, 20))
# 在函數名add_lambda后面加上括號并傳入參數,才能正確地輸出結果
把上述代碼進行合并操作,可以無需聲明函數名add_lambda
,直接傳入兩個數字10
和20
,得到結果:
# 這里的(lambda x,y: x+y)等價于上面的函數名add_lambda
# (lambda x,y: x+y)(10, 20)等價于add_lambda(10, 20)
# 顯然add_lambda這個函數名是不必要的,故稱之為"lambda匿名函數"print(lambda x,y: x+y)
# 輸出形如 <function <lambda> at 0x00000249F7AD7B00> 的結果
# 這一長串復雜的十六進制數是該匿名函數的內存地址print((lambda x,y: x+y)(10, 20))
# 在匿名函數后面加上括號并傳入參數,才能正確地輸出結果
根據上述兩個例子已經能夠看出端倪了,有以下重要結論:
lambda
匿名函數本質上是一個函數,而不是一個變量,使用lambda
匿名函數可以得到一個函數。- 定義
lambda
匿名函數的語法為:lambda [形參]: 返回值
,形參的數量可以為0
,即支持定義無參數匿名函數。 - 使用
lambda
匿名函數的語法為:(lambda [形參]: 返回值) ([實參])
,一般情況下,實參的數量應該和定義的形參數量一致。
*注:上述語句中的中括號
[]
表示非必須結構。
最后我們來看lambda
匿名函數在算法題中的幾個經典用法。
defaultdict()
使用內置模塊collections
中的defaultdict(func)
,能夠將哈希表的值value
的默認類型設置為func
,其中func
是某種數據類型****初始化函數的函數名,如int
,list
,dict
等等。
假設我們想要value
的默認值為1
,其中一種方法通過def
關鍵字定義一個叫做get_one()
的函數,并且將函數名get_one
作為函數名傳入defaultdict(func)
中。
from collections import defaultdict# 使用def關鍵字進行函數定義
def get_one():return 1# 哈希表d的value的默認值即為1
# 注意這里傳入的是函數名get_one,而不是調用函數get_one()
d = defaultdict(get_one)# 輸出1
print(d[0])
通過前面分析我們知道,get_one
這個函數名實際上等同于lambda: 1
,故我們不需要對get_one()
顯式地進行定義,使用lambda
匿名函數能夠使得代碼更加整潔。
from collections import defaultdict# 哈希表d1的value的默認值即為1
d_lambda = defaultdict(lambda: 1)# 輸出1
print(d_lambda[0])
sort()
方法或內置函數sorted()
sort()
方法和內置函數sorted()
均包含key
參數,用來指定排序的依據。key
參數傳入的也是一個函數名func
,可以簡單理解為對列表中的所有元素均使用函數func
后,以得到的結果為依據對原列表進行排序。
假設我們想要對字符串按照長度來排序,可以指定len()
內置函數為排序依據。
lst = ["123", "4567", "0", "12", "789"]# 注意這里key參數傳入是函數名len,而不是調用函數len()
lst.sort(key = len)# 輸出['0', '12', '123', '789', '4567']
print(lst)
上述代碼也可以寫成lambda
匿名函數的形式。
lst = ["123", "4567", "0", "12", "789"]# 注意這里key參數傳入是函數名len,而不是調用函數len()
lst.sort(key = lambda x: len(x))# 輸出['0', '12', '123', '789', '4567']
print(lst)
如果對于長度相同的字符串,我們還想要按照數字序降序排列,那么僅用len()
函數是無法完成的,只能通過進一步完善lambda
匿名函數來完成。
lst = ["123", "4567", "0", "12", "789"]# 注意這里key參數傳入是函數名len,而不是調用函數len()
lst.sort(key = lambda x: (len(x), -int(x)))# 輸出['0', '12', '789', '123', '4567']
print(lst)
- 內置函數
map()
內置函數map(func, iter)
包含兩個參數,分別是函數名func
和可迭代對象iter
。這里的func
參數不僅可以傳入已有的內置函數或自定義函數的函數名,也可以直接用lambda
匿名函數完成。
譬如想要對由二進制字符串組成的列表lst_bin
中的每一個字符串用先導0
填充至長度為4
,如果我們使用def
關鍵字定義一個叫做get_pre_0()
的函數,可以這樣實現:
# 使用def關鍵字進行函數定義
# (4-len(s))能夠獲得應該填充的先導零"0"的個數
def get_pre_0(s):return (4-len(s))*"0" + slst_bin = ["10", "101", "1100", "1", "0"]# 注意這里key參數傳入是函數名get_pre_0,而不是調用函數get_pre_0()
lst_with_pre_0 = list(map(get_pre_0, lst_bin))# 輸出['0010', '0101', '1100', '0001', '0000']
print(lst_with_pre_0)
使用lambda
匿名函數,無需具體定義函數get_pre_0()
,亦可完成同樣操作。
lst_bin = ["10", "101", "1100", "1", "0"]# 使用lambda匿名函數,無需具體定義函數get_pre_0()
lst_with_pre_0_lambda = list(map(lambda x: (4-len(x))*"0" + x, lst_bin))# 輸出['0010', '0101', '1100', '0001', '0000']
print(lst_with_pre_0_lambda)
華為OD算法/大廠面試高頻題算法練習沖刺訓練
-
華為OD算法/大廠面試高頻題算法沖刺訓練目前開始常態化報名!目前已服務100+同學成功上岸!
-
課程講師為全網50w+粉絲編程博主@吳師兄學算法 以及小紅書頭部編程博主@閉著眼睛學數理化
-
每期人數維持在20人內,保證能夠最大限度地滿足到每一個同學的需求,達到和1v1同樣的學習效果!
-
60+天陪伴式學習,40+直播課時,300+動畫圖解視頻,300+LeetCode經典題,200+華為OD真題/大廠真題,還有簡歷修改、模擬面試、專屬HR對接將為你解鎖
-
可上全網獨家的歐弟OJ系統練習華子OD、大廠真題
-
可查看鏈接 大廠真題匯總 & OD真題匯總(持續更新)
-
綠色聊天軟件戳
od1336
了解更多