你們好,今天給你們帶來的是有關於Python裏面的lambda表達式的我的總結。lambda在Python裏面的用處很廣,但說實話,我我的以爲有關於lambda的討論不是如何使用,而是該不應用的問題。接下來仍是經過一些我練習的實例和你們分享個人學習經歷,可能最後你也會得出和我同樣的結論。python
好啦,首先讓咱們先搞明白基礎定義,lambda究竟是什麼?api
Lambda表達了Python中用於建立匿名函數的特殊語法。咱們將lambda語法自己稱爲lambda表達式,從這裏獲得的函數稱之爲lambda函數。bash
其實總結起來,lambda能夠理解爲一個小的匿名函數,lambda函數可使用任意數量的參數,但只能有一個表達式,估計有JavaScript ES6經驗的朋友們聽上去會很親切,具體函數表達式以下:數據結構
讓咱們參考上面的定義模板和參數, 直接看一個最簡單的例子:app
add_one = lambda x:x+1 # 1個參數,執行操做爲+1
add_nums = lambda x,y:x+y # 2個參數,執行操做爲相加
print(add_one(2)) # 調用add_one
print(add_nums(3,7)) # 調用add_nums
>>> 3
10
複製代碼
相比你們已經發現lambda匿名函數的特色了,就是對於較爲簡單的功能,無需本身def一個了,單行就能夠寫下,傳參和方法內容一鼓作氣函數
接下來讓咱們看看lambda的實際應用,就我本身使用lambda的體驗來講,歷來沒有單獨用過,lambda通常狀況下是和map,filter,reduce這些超棒的內置函數以及dict,list,tuple,set 等數據結構混用,這樣才能發揮它的最大效果,若是有朋友還不太熟悉這些內置函數,能夠看一下我前一篇文章 Python 進階之路 (五) map, filter, reduce, zip 總結post
下面讓咱們一個個來看學習
首先是lambda+map的組合,先看下面這個例子:ui
numbers = [1,2,3,4,5]
add_one = list(map(lambda n:n+1,numbers)) #map(fun,sequence)
print(list(add_one))
print(tuple(add_one))
Out: [2, 3, 4, 5, 6]
(2, 3, 4, 5, 6)
複製代碼
這個上一篇文章的例子,實現一個List或者Tuple中每一個元素+1,讓咱們看一下這個例子中map和lambda的用法:spa
def add(num):
return num+1
numbers = [1,2,3,4,5]
add_one = list(map(add,numbers))
print(add_one)
print(tuple(add_one))
複製代碼
顯然易見,這裏的add方法有點多餘,因此用lambda代替是個好的選擇。
下面這段代碼,這是我本身備份日誌時寫的,命名不是很規範:
from datetime import datetime as dt
logs = ['serverLog','appLog','paymentLog']
format ='_{}.py'.format(dt.now().strftime('%d-%m-%y'))
result =list(map(lambda x:x+format,logs)) # 利用map+lambda 實現字符串拼接
print(result)
Out:['serverLog_11-02-19.py', 'appLog_11-02-19.py', 'paymentLog_11-02-19.py']
複製代碼
這裏和剛纔的加1例子差很少,可是換成了字符串的拼接,然而我這裏用lambda並非很好的解決方案,最後咱們會說。
如今你們應該對map + lambda 有一些感受了,讓咱們再來個和dict字典互動的例子:
person =[{'name':'Lilei',
'city':'beijing'},
{'name':'HanMeiMei',
'city':'shanghai'}]
names=list(map(lambda x:x['name'],person))
print(names)
Out:['Lilei', 'HanMeiMei']
複製代碼
好了,看到這裏對於map+lambda的用法你們已經很清楚了應該~
lambda和filter的組合也很常見,用於特定篩選條件下,如今讓咱們來看上篇文章filter的例子,就應該很好理解了:
numbers = [0, 1, 2, -3, 5, -8, 13]
# 提取奇數
result = filter(lambda x: x % 2, numbers)
print("Odd Numbers are :",list(result))
# 提取偶數
result = filter(lambda x: x % 2 == 0, numbers)
print("Even Numbers are :",list(result))
#提取正數
result = filter(lambda x: x>0, numbers)
print("Positive Numbers are :",list(result))
Out:Odd Numbers are : [1, -3, 5, 13]
Even Numbers are : [0, 2, -8]
Positive Numbers are : [1, 2, 5, 13]
複製代碼
這裏無非就是咱們把filter(fun,sequence)裏面的fun換成了咱們的lambda,只是lambda的函數部分(x%2,x%2==0,x>0)都是能夠返回True或者False來判斷的,符合fiter的要求,用剛纔李雷和韓梅梅的例子也是一個道理:
person =[{'name':'Lilei',
'city':'beijing'},
{'name':'HanMeiMei',
'city':'shanghai'}]
names=list(filter(lambda x:x['name']=='Lilei',person)) # 提取李雷的信息
print(names)
Out:[{'name': 'Lilei', 'city': 'beijing'}]
複製代碼
仍是讓咱們看一下上篇文章的例子:
from functools import reduce # Only Python 3
numbers = [1,2,3,4]
result_multiply = reduce((lambda x, y: x * y), numbers)
result_add = reduce((lambda x,y: x+y), numbers)
print(result_multiply)
print(result_add)
Out:24
10
複製代碼
這個例子用lambda和reduce的配合實現了list求累積和和累積乘法。 有意思的是這個例子具備兩面性,一方面展現了lambda和reduce如何一塊兒使用,另外一方面也引出了接下來我想說的重點:lambda真的值得用嗎?到底應該怎麼用?
經過上面的例子你們已經看到了lambda的實際應用場景,可是我我的以爲lambda的缺點略多於優勢,應該儘可能避免使用
首先,這僅僅是個人我的見解哈,但願你們理解,我爲何這麼說呢,首先讓咱們拿lambda方法和常規def作個對比,我發現lambda和def的主要不一樣點以下:
有關優勢你們均可以看到,我主要想說一下它的缺點,首先,從真正需求出發,咱們在大多數時候是不須要lambda的,由於總能夠找到更好的替代方法,如今咱們一塊兒看一下剛纔lambda+reduce 的例子,咱們用lambada實現的結果以下:
from functools import reduce # Only Python 3
numbers = [1,2,3,4]
result_multiply = reduce((lambda x, y: x * y), numbers)
result_add = reduce((lambda x,y: x+y), numbers)
複製代碼
這裏用lambda並無實現簡單高效的目的,由於咱們有現成的sum和mul方法能夠用:
from functools import reduce
from operator import mul
numbers = [1,2,3,4]
result_add = sum(numbers)
result_multiply =reduce(mul,numbers)
print(result_add)
print(result_multiply)
Out: 10
24
複製代碼
結果是同樣的,可是顯然用sum和mul的方案更加高效。再舉個常見的例子說明,假如咱們有一個list存儲了各類顏色,如今要求把每一個顏色首字母大寫,若是用lambda寫出是這樣:
colors = ['red','purple','green','blue']
result = map(lambda c:c.capitalize(),colors)
print(list(result))
Out:['Red', 'Purple', 'Green', 'Blue']
複製代碼
看着彷佛不錯,挺簡潔的,可是咱們有更好的方法:
colors = ['red','purple','green','blue']
result = [c.capitalize() for c in colors]
print(result)
Out:['Red', 'Purple', 'Green', 'Blue']
複製代碼
用sorted還能處理首字母不規範的狀況,連排序都省了:
colors = ['Red','purple','Green','blue']
print(sorted(colors,key=str.capitalize))
Out:['blue', 'Green', 'purple', 'Red']
複製代碼
還有一個主要緣由就是: lambda函數沒有函數名稱。因此在代碼交接,項目移植的場景中會給團隊帶來不少困難,多寫個函數add_one()沒什麼壞處,由於你們都很容易理解,知道它是執行+1的功能,可是若是團隊裏你在本身負責的模塊使用了不少lambda,會給其餘人理解帶來不少麻煩
話又說回來,存在即合理,那麼真正須要咱們使用lambda的是哪些場景呢:
還有一種場景很是適用,就是在給其餘人制造本身很專業的錯覺時,好比:
哎呀,小老弟,據說你學了Python,知道lambda不? 沒聽過?不行啊,白學了!來來來,讓我給你講講。。。此處省略1萬字
今天爲你們九淺一深地講解了lambda的用法和使用場景,所謂九淺一深,就是90%狀況下用於建立簡單的匿名函數,10%的狀況稍微複雜(這個藉口找的太好了)
總而言之,任何事情都具備兩面性,每次當你想用lambda以前應該先停下來,問問本身是否是真的須要它。
固然,若是須要和別人忽悠的時候都是正反一張嘴,lambda是好是壞全看咱們本身怎麼說,吹牛時請遵照以下原則,屢試不爽:
若是你說一個女大學生晚上賣淫就是可恥,但若是改爲一個妓女利用業餘時間努力學習就勵志多了!
lambda也是如此