lambda是Python編程語言中使用頻率較高的一個(gè)關(guān)鍵字。那么,什么是lambda?它有哪些用法?
一、語法
lambda [ arg1 [arg2, arg3, … argN] ] : expression
– 《Python核心編程》
從《Python核心編程》書本中包含了以上lambda表達(dá)式的表述。也就是說在lambda右側(cè)的式子中,冒號左邊的為參數(shù)值,右邊的為計(jì)算表達(dá)式。
二、 實(shí)例說明
1.單層參數(shù)求和
現(xiàn)在假設(shè)需要對兩個(gè)數(shù)進(jìn)行求和運(yùn)算。對于正常的邏輯代碼,不難寫出如下代碼:
def sum(x, y):
return x + y
而在lambda中,我們可以這樣來寫:
p = lambda x, y: x + y
代碼簡潔了許多
2.嵌套參數(shù)求和
注:下面的一段代碼實(shí)際上是存在語法錯(cuò)誤的,此代碼的目的純粹只是為了說明問題。請勿模仿
def sum_outer(x=0):
def sum_inner(y):
return x + y
采用lambda改寫后的代碼如下:
def test_lamdba2(x=0):
return lambda y: x + y
三、特性
lambda函數(shù)有如下特性:
- lambda函數(shù)是匿名的:所謂匿名函數(shù),通俗地說就是沒有名字的函數(shù)。lambda函數(shù)沒有名字。
- lambda函數(shù)有輸入和輸出:輸入是傳入到參數(shù)列表argument_list的值,輸出是根據(jù)表達(dá)式expression計(jì)算得到的值。
- lambda函數(shù)一般功能簡單:單行expression決定了lambda函數(shù)不可能完成復(fù)雜的邏輯,只能完成非常簡單的功能。由于其實(shí)現(xiàn)的功能一目了然,甚至不需要專門的名字來說明。
四、用法說明
由于lambda語法是固定的,其本質(zhì)上只有一種用法,那就是定義一個(gè)lambda函數(shù)。在實(shí)際中,根據(jù)這個(gè)lambda函數(shù)應(yīng)用場景的不同,可以將lambda函數(shù)的用法擴(kuò)展為以下幾種:
1.將lambda函數(shù)賦值給一個(gè)變量,通過這個(gè)變量間接調(diào)用該lambda函數(shù)。
例如,執(zhí)行語句add=lambda x, y: x+y,定義了加法函數(shù)lambda x, y: x+y,并將其賦值給變量add,這樣變量add便成為具有加法功能的函數(shù)。例如,執(zhí)行add(1,2),輸出為3。
2.將lambda函數(shù)賦值給其他函數(shù),從而將其他函數(shù)用該lambda函數(shù)替換。
例如,為了把標(biāo)準(zhǔn)庫time中的函數(shù)sleep的功能屏蔽(Mock),我們可以在程序初始化時(shí)調(diào)用:time.sleep=lambda x:None。這樣,在后續(xù)代碼中調(diào)用time庫的sleep函數(shù)將不會(huì)執(zhí)行原有的功能。例如,執(zhí)行time.sleep(3)時(shí),程序不會(huì)休眠3秒鐘,而是什么都不做。
3.將lambda函數(shù)作為其他函數(shù)的返回值,返回給調(diào)用者。
函數(shù)的返回值也可以是函數(shù)。例如return lambda x, y: x+y返回一個(gè)加法函數(shù)。這時(shí),lambda函數(shù)實(shí)際上是定義在某個(gè)函數(shù)內(nèi)部的函數(shù),稱之為嵌套函數(shù),或者內(nèi)部函數(shù)。對應(yīng)的,將包含嵌套函數(shù)的函數(shù)稱之為外部函數(shù)。內(nèi)部函數(shù)能夠訪問外部函數(shù)的局部變量,這個(gè)特性是閉包(Closure)編程的基礎(chǔ),在這里我們不展開。
4.將lambda函數(shù)作為參數(shù)傳遞給其他函數(shù)。
部分Python內(nèi)置函數(shù)接收函數(shù)作為參數(shù)。典型的此類內(nèi)置函數(shù)有這些。
filter函數(shù)。此時(shí)lambda函數(shù)用于指定過濾列表元素的條件。例如filter(lambda x: x % 3 == 0, [1, 2, 3])指定將列表[1,2,3]中能夠被3整除的元素過濾出來,其結(jié)果是[3]。
sorted函數(shù)。此時(shí)lambda函數(shù)用于指定對列表中所有元素進(jìn)行排序的準(zhǔn)則。例如sorted([1, 2, 3, 4, 5, 6, 7, 8, 9], key=lambda x: abs(5-x))將列表[1, 2, 3, 4, 5, 6, 7, 8, 9]按照元素與5距離從小到大進(jìn)行排序,其結(jié)果是[5, 4, 6, 3, 7, 2, 8, 1, 9]。
map函數(shù)。此時(shí)lambda函數(shù)用于指定對列表中每一個(gè)元素的共同操作。例如map(lambda x: x+1, [1, 2,3])將列表[1, 2, 3]中的元素分別加1,其結(jié)果[2, 3, 4]。
reduce函數(shù)。此時(shí)lambda函數(shù)用于指定列表中兩兩相鄰元素的結(jié)合條件。例如reduce(lambda a, b: '{}, {}'.format(a, b), [1, 2, 3, 4, 5, 6, 7, 8, 9])將列表 [1, 2, 3, 4, 5, 6, 7, 8, 9]中的元素從左往右兩兩以逗號分隔的字符的形式依次結(jié)合起來,其結(jié)果是'1, 2, 3, 4, 5, 6, 7, 8, 9'。
另外,部分Python庫函數(shù)也接收函數(shù)作為參數(shù),例如gevent的spawn函數(shù)。此時(shí),lambda函數(shù)也能夠作為參數(shù)傳入。
五、變量作用域說明
關(guān)于變量在Lambda中的作用域從上面的幾幅圖中也可以看出一二來,主要可以做出以下幾點(diǎn)的總結(jié):
- 對局部變量可見
- 對全局變量可見
- 對當(dāng)前層傳入的參數(shù)可見
- 對上層函數(shù)傳入的參數(shù)可見
- 對上層Lambda傳入的參數(shù)可見
六、Lambda評價(jià)
優(yōu)點(diǎn)
- 在普通代碼里幾行的代碼,在Lambda中只需要一行就可以解決。所以代碼比以前更簡潔了
- 可以在某一個(gè)方法內(nèi)部定義,這樣可以提高操作的便捷性
缺點(diǎn) - Lambda是一個(gè)匿名函數(shù),因?yàn)槭悄涿?,所以可讀性變差了
- 有時(shí)候有多個(gè)Lambda嵌套(就像實(shí)例中的第3點(diǎn)一樣),讓程序變得難以理解