摘要:好啦,首先讓我們先搞明白基礎(chǔ)定義,到底是什么表達了中用于創(chuàng)建匿名函數(shù)的特殊語法。其實總結(jié)起來,可以理解為一個小的匿名函數(shù),函數(shù)可以使用任意數(shù)量的參數(shù),但只能有一個表達式。
lambda是什么
大家好,今天給大家?guī)淼氖怯嘘P(guān)于Python里面的lambda表達式詳細解析。lambda在Python里面的用處很廣,但說實話,我個人認為有關(guān)于lambda的討論不是如何使用的問題,而是該不該用的問題。接下來還是通過大量實例和大家分享我的學習體驗,可能最后你也會得出和我一樣的結(jié)論。
好啦,首先讓我們先搞明白基礎(chǔ)定義,lambda到底是什么?
Lambda表達了Python中用于創(chuàng)建匿名函數(shù)的特殊語法。我們將lambda語法本身稱為lambda表達式,從這里得到的函數(shù)稱之為lambda函數(shù)。
其實總結(jié)起來,lambda可以理解為一個小的匿名函數(shù),lambda函數(shù)可以使用任意數(shù)量的參數(shù),但只能有一個表達式。估計有JavaScript ES6經(jīng)驗的朋友們聽上去會很親切,具體函數(shù)表達式如下:
模板: lambda argument: manipulate(argument)
參數(shù):argument就是這個匿名函數(shù)傳入的參數(shù),冒號后面是我們對這個參數(shù)的操作方法
讓我們參考上面的定義模板和參數(shù), 直接看一個最簡單的例子:
add_one = lambda x:x+1 # 1個參數(shù),執(zhí)行操作為+1 add_nums = lambda x,y:x+y # 2個參數(shù),執(zhí)行操作為相加 print(add_one(2)) # 調(diào)用add_one print(add_nums(3,7)) # 調(diào)用add_nums >>> 3 10
相比大家已經(jīng)發(fā)現(xiàn)lambda匿名函數(shù)的特點了,就是對于較為簡單的功能,無需自己def一個了,單行就可以寫下,傳參和執(zhí)行方法一氣呵成
lambda用法詳解接下來讓我們看看lambda的實際應用,就我自己使用lambda的體驗來說,從來沒有多帶帶用過,lambda一般情況下是和map,filter,reduce這些超棒的內(nèi)置函數(shù)以及dict,list,tuple,set 等數(shù)據(jù)結(jié)構(gòu)混用,這樣才能發(fā)揮它的最大效果,如果有朋友還不太熟悉這些內(nèi)置函數(shù),可以看一下我上一篇文章 Python 進階之路 (五) map, filter, reduce, zip 一網(wǎng)打盡
好了,閑話少說,下面讓我們一個個來看
lambda + map首先出場的是lambda+map的組合,先看下面這個例子:
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)
這個是我們上一期的例子,實現(xiàn)一個數(shù)組(元組)每個元素+1,讓我們回憶一下map的用法
map(fun,sequence),fun是傳遞的方法,sequence是一個可迭代的序列,這里我們的fun就是匿名函數(shù)
lambda n:n+1,這里非常完美的解釋了lambda的設(shè)計初衷,因為如果沒有l(wèi)ambda,我們的解決方案是這樣:
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代替是個好的選擇。讓我們再看下一個例子,這是我自己備份日志時寫的一小段代碼,命名不是很規(guī)范:
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 實現(xiàn)字符串拼接 print(result) Out:["serverLog_11-02-19.py", "appLog_11-02-19.py", "paymentLog_11-02-19.py"]
這里和剛才的加1例子差不多,但是換成了字符串的拼接,然而我這里用lambda并不是很好的解決方案,最后我們會說,現(xiàn)在大家應該對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的用法大家已經(jīng)很清楚了應該~
lambda + filterlambda和filter的組合也很常見,用于特定篩選條件下,現(xiàn)在讓我們來看上篇文章filter的例子,就應該很好理解了:
numbers = [0, 1, 2, -3, 5, -8, 13] # 提取奇數(shù) result = filter(lambda x: x % 2, numbers) print("Odd Numbers are :",list(result)) # 提取偶數(shù) result = filter(lambda x: x % 2 == 0, numbers) print("Even Numbers are :",list(result)) #提取正數(shù) 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的函數(shù)部分(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"}]lambda + reduce
還是讓我們看一下上篇文章的例子:
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的配合實現(xiàn)了list求累積和和累積乘法。
有意思的是這個例子具有兩面性,一方面展示了lambda和reduce如何一起使用,另一方面也引出了接下來我想說的重點:lambda真的值得用嗎?到底應該怎么用?
通過上面的例子大家已經(jīng)看到了lambda的實際應用場景,但是這里我想和大家分享一下我的看法:我認為lambda的缺點略多于優(yōu)點,應該避免過度使用lambda
首先,這僅僅是我的個人看法哈,希望大家理解,我為什么這么說呢,首先讓我們拿lambda方法和常規(guī)def做個對比,我發(fā)現(xiàn)lambda和def的主要不同點如下:
可以立即傳遞(無需變量)
只需一行代碼,簡潔(未必高效)
可以會自動返回,無需return
lambda函數(shù)沒有函數(shù)名稱
有關(guān)優(yōu)點大家都可以看到,我主要想說一下它的缺點,首先,從真正需求出發(fā),我們在大多數(shù)時候是不需要lambda的,因為總可以找到更好的替代方法,現(xiàn)在我們一起看一下剛才lambda+reduce 的例子,我們用lambada實現(xiàn)的結(jié)果如下:
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并沒有實現(xiàn)簡單高效的目的,因為我們有現(xiàn)成的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
結(jié)果是一樣的,但是顯然用sum和mul的方案更加高效。再舉個常見的例子說明,假如我們有一個list存儲了各種顏色,現(xiàn)在要求把每個顏色首字母大寫,如果用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還能處理首字母不規(guī)范的情況,連排序都省了:
colors = ["Red","purple","Green","blue"] print(sorted(colors,key=str.capitalize)) Out:["blue", "Green", "purple", "Red"]
還有一個主要原因就是: lambda函數(shù)沒有函數(shù)名稱。所以在代碼交接,項目移植的場景中會給團隊帶來很多困難,多寫個函數(shù)add_one()沒什么壞處,因為大家都很容易理解,知道它是執(zhí)行+1的功能,但是如果團隊里你在自己負責的模塊使用了很多l(xiāng)ambda,會給其他人理解帶來很多麻煩
適合lambda的場景話又說回來,存在即合理,那么真正需要我們使用lambda的是哪些場景呢:
你需要的方法是很簡單的(+1,字符串拼接等),該函數(shù)不值得擁有一個名字
使用lambda表達式,會比我們能想到的函數(shù)名稱更容易理解
除了lambda,沒有任何python提供的函數(shù)可以實現(xiàn)目的
團隊中所有成員都掌握lambda,大家同意你用
還有一種場景非常適用,就是在給其他人制造自己很專業(yè)的錯覺時,比如:
哎呀,小老弟,聽說你學了Python,知道lambda不? 沒聽過?不行啊,白學了!來來來,讓我給你講講。。。此處省略1萬字總結(jié)
今天為大家九淺一深地講解了lambda的用法和使用場景,所謂九淺一深,就是90%情況下用于創(chuàng)建簡單的匿名函數(shù),10%的情況稍微復雜(我這個借口找的太好了)
總而言之就是,任何事情都具有兩面性,我們在使用lambda之前應該先停下來,問問自己是不是真的需要它。
當然,如果需要和別人忽悠的時候都是正反一張嘴,lambda是好是壞全看我們自己怎么說,吹牛時請遵守如下原則,屢試不爽:
如果你說一個女大學生晚上賣淫就是可恥,但如果改成一個妓女利用業(yè)余時間努力學習就勵志多了!
lambda也是如此
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/43171.html
摘要:將每一行作為返回,其中是每行中的列名。對于每一行,都會生成一個對象,其中包含和列中的值。它返回一個迭代器,是迭代結(jié)果都為的情況。深度解析至此全劇終。 簡單實戰(zhàn) 大家好,我又來了,在經(jīng)過之前兩篇文章的介紹后相信大家對itertools的一些常見的好用的方法有了一個大致的了解,我自己在學完之后仿照別人的例子進行了真實場景下的模擬練習,今天和大家一起分享,有很多部分還可以優(yōu)化,希望有更好主意...
摘要:新的標準上周,語言規(guī)范的最終草案,第版,被提交給大會進行審查。從那時起,標準委員會就一直致力于的制定直至今日。是語言的一次重大的升級。這種說法也可以被看作是委員會給出的一個承諾。 簡介 歡迎來到深度探索 ES6!在這個新的周系列里,我們將探索 ECMAScript 6。這是一種 JavaScript 語言即將到來的新版本。ES6 包含了很多新的語言功能,且這些語言功能使得 JS 更加強...
摘要:中文資料導航官網(wǎng)七牛鏡像深入淺出系列進階必讀中文文檔被誤解的編寫實戰(zhàn)系列熱門模塊排行榜,方便找出你想要的模塊多線程,真正的非阻塞淺析的類利用編寫異步多線程的實例中與的區(qū)別管道拒絕服務(wù)漏洞高級編程業(yè)界新聞看如何評價他們的首次嘗鮮程序員如何說服 node.js中文資料導航 Node.js HomePage Node官網(wǎng)七牛鏡像 Infoq深入淺出Node.js系列(進階必讀) Nod...
摘要:新年快樂大家好,今天是大年初二,身在國外沒有過年的氛圍,只能踏實寫寫文章,對社區(qū)做點貢獻,在此祝大家新年快樂上一期為大家梳理了一些的進階用法,今天我們來看字典的相關(guān)技巧,我個人在編程中對字典的使用非常頻繁,其實對于不是非常大的數(shù)據(jù)存儲需求, 新年快樂 大家好,今天是大年初二,身在國外沒有過年的氛圍,只能踏實寫寫文章,對社區(qū)做點貢獻,在此祝大家新年快樂!上一期為大家梳理了一些List的進...
閱讀 1244·2023-04-25 18:57
閱讀 2127·2023-04-25 16:28
閱讀 3926·2021-11-24 09:39
閱讀 3631·2021-11-16 11:45
閱讀 1816·2021-10-13 09:40
閱讀 1260·2019-08-30 15:52
閱讀 1715·2019-08-30 10:57
閱讀 657·2019-08-29 16:55