python 中定義函式有兩種方法,一種是用常規方式 def 定義,函式要指定名字,第二種是用 lambda 定義,不需要指定名字,稱為 lambda 函式。
lambda 函式又稱匿名函式,匿名函式就是沒有名字的函式,函式沒有名字也行?當然可以啦。有些函式如果只是臨時一用,而且它的業務邏輯也很簡單時,就沒必要非給它取個名字不可。
好比電影裡面的群眾演員,往往他們的戲份很少,最多是襯托主演,跑跑龍套,他們需要名字嗎?不需要,因為他們僅僅只是臨時出鏡,下次可能就用不著了,所以犯不著費心思給他們每個人編個號取個名字,畢竟取個優雅的名字是很費勁的事情。
先來看個簡單 lambda 函式
>>>lambdax,
y: x+
y<
function
<
lambda
>
at0x102bc1c80
>
x 和 y 是函式的兩個引數,冒號後面的表示式是函式的返回值,你能一眼看出這個函式就是是在求兩個變數的和,但作為乙個函式,沒有名字如何使用呢?這裡我們暫且給這個匿名函式繫結乙個名字,這樣使得我們呼叫匿名函式成為可能
>>>add=
lambdax,
y: x+
y>>>
add<
function
<
lambda
>
at0x102bc2140
>
>>>
add(1,
2)3
它等同於常規函式
>>>defadd2(x
,y):
...returnx+
y...
>>>
add2
<
function add2
at0x102bc1c80
>
>>>
add2(1
,2)3
如果定義匿名函式,還要給它繫結乙個名字的話,有點畫蛇添足,通常是直接使用 lambda 函式。那麼 lamdba 函式的正確使用場景在哪呢?
1、函式式程式設計
儘管 python 算不上是一門純函式式程式語言,但它本身提供了很多函式式程式設計的特性,像 map、reduce、filter、sorted 這些函式都支援函式作為引數,lambda 函式就可以應用在函式式程式設計中。
請看題:乙個整數列表,要求按照列表中元素的絕對值大小公升序排列,你會怎麼做?思考一分鐘往下看
>>>list1= [
3,5,
-4,-
1,0,
-2,-
6]>>>
sorted
(list1
,key
=lambdax:
abs(x))
[0,-
1,-2
,3,-
4,5,
-6]
排序函式 sorted 支援接收乙個函式作為引數,該引數作為 sorted 的排序依據,這裡按照列表元素的絕對值進行排序,當然,我也可以用普通函式來實現:
>>>deffoo(x
):...return
abs(x)
...
>>>
sorted
(list1
,key
=foo)[
0,-1
,-2,
3,-4
,5,-
6]
只不過是這種方式**看起來不夠 pythonic 而已。
2、閉包
閉包本身是乙個晦澀難懂的概念,它可以專門單獨用一篇文章來介紹,不過在這裡我們可以簡單粗暴地理解為閉包就是乙個定義在函式內部的函式,閉包使得變數即使脫離了該函式的作用域範圍也依然能被訪問到。
來看乙個用 lambda 函式作為閉包的例子。
>>>defmy_add(n
):...return
lambdax:
x+n...
>>>
add_3
= my_add(3
)>>>
add_3(7
)10
這裡的 lambda 函式就是乙個閉包,在全域性作用域範圍中,add_3(7) 可以正常執行且返回值為10,之所以返回10是因為在 my_add 區域性作用域中,變數 n 的值在閉包的作用使得它在全域性作用域也可以被訪問到。
換成常規函式也可以實現閉包,只不過是這種方式稍顯囉嗦。
>>>defmy_add(n
):...def(x
):...returnx+
n...
return
...
>>>
add_5
= my_add(5
)>>>
add_5(2
)7
那麼是不是任何情況 lambda 函式都要比常規函式更清晰明了呢?看這個例子:
f = lambda x: [[y for j, y in enumerate(set(x)) if (i >> j) & 1] for i in range(2**len(set(x)))]
這是乙個返回某個集合的所有子集的 lambda 函式,你看明白了嗎?我是很難一眼看出來
什麼時候使用引用 什麼時候使用指標
使用引用引數的主要原因有兩個 程式設計師能修改呼叫函式中的資料物件 通過傳遞引用而不是整個資料 物件,可以提高程式的執行速度一般的原則 對於使用引用的值而不做修改的函式 如果資料物件很小,如內建資料型別或者小型結構,則按照值傳遞 如果資料物件是陣列,則使用指標 唯一的選擇 並且指標宣告為指向cons...
什麼時候使用抽象類, 什麼時候使用介面
介面是一種協定,抽象類則相當於類模板。使用抽象類,而不要使用介面來分離協定與實現。如果需要提供多型層次結構的值型別,使用介面。如果乙個型別必須實現多個協定,或者協定適用於多種型別,使用介面。雖然抽象類和介面都支援將協定與實現分離開來,但介面不能指定以後版本中的新成員,而抽象類可以根據需要新增成員以支...
什麼時候使用介面,什麼時候使用抽象類
使用抽象類是為了 的復用,而使用介面的動機是為了實現多型性。抽象類適合用來定義某個領域的固有屬性,也就是本質,介面適合用來定義某個領域的擴充套件功能。一 什麼時候使用抽象類?當2個或多個類中有重複部分的時候,我們可以抽象出來乙個基類,如果希望這個基類不能被例項化,就可以把這個基類設計成抽象類。當需要...