python lambda 判断_Python lambda
引言
前段時(shí)間,沒(méi)事兒時(shí)翻看了自己剛參加工作時(shí)寫(xiě)的一些代碼,發(fā)現(xiàn)代碼中有好幾處分別都用到了lambda表達(dá)式,從代碼中會(huì)發(fā)現(xiàn)那時(shí)候的自己對(duì)lambda理解的不算深刻,lambda的本質(zhì),為什么要用lambda而不用def定義函數(shù)等這些都沒(méi)有系統(tǒng)的掌握。于是后面花了一些時(shí)間重新梳理了自己對(duì)lambda的認(rèn)識(shí)。
lambda介紹
lambda是python中的一個(gè)關(guān)鍵字,實(shí)際開(kāi)發(fā)中常用lambda表達(dá)式的方式創(chuàng)建匿名函數(shù),比如 lambda a, b: a+b,表示定義了一個(gè)匿名函數(shù),該函數(shù)包含a、b兩個(gè)參數(shù),并返回a與b的和。lambda表達(dá)式返回的是一個(gè)函數(shù)對(duì)象,可通過(guò)函數(shù)對(duì)象來(lái)調(diào)用定義的匿名函數(shù),比如my_func = lambda a, b: a+b,my_func(2, 3)則表示調(diào)用lambda定義的匿名函數(shù);(lambda a, b: a + b)(2, 3)則是另一種調(diào)用方式,具體操作如下:
>>> my_func = lambda a, b: a + b
>>> type(my_func)
>>> my_func
at 0x0000000002E60438>
>>> my_func(2, 3)
5
>>> (lambda a, b: a + b)(2, 3)
5
剖析lambda創(chuàng)建匿名函數(shù)
lambda定義匿名函數(shù)的格式為:lambda parameters: expression,其中parameters表示定義一個(gè)或多個(gè)參數(shù),參數(shù)類型與def一樣,支持普通參數(shù)、默認(rèn)參數(shù)、可變參數(shù)、關(guān)鍵字參數(shù)。lambda定義的匿名函數(shù)等價(jià)于如下的函數(shù)定義:
def (parametes):
return expression
# 指函數(shù)名稱
比如:lambda x: x + 2 等價(jià)于 def func_name(x): return x + 2;lambda a, b: a ** b 等價(jià)于 def func_name(a, b): return a ** b。其中func_name是自定義的函數(shù)名,我們也可以通過(guò)dis工具分析def與lambda定義的兩類函數(shù)的字節(jié)碼的關(guān)系:
>>> import dis
>>> def my_func(a, b, c):
return (a + b) * c
>>> dis.dis(my_func)
3 0 LOAD_FAST 0 (a)
3 LOAD_FAST 1 (b)
6 BINARY_ADD
7 LOAD_FAST 2 (c)
10 BINARY_MULTIPLY
11 RETURN_VALUE
>>> dis.dis(lambda a, b, c: (a + b) * c)
2 0 LOAD_FAST 0 (a)
3 LOAD_FAST 1 (b)
6 BINARY_ADD
7 LOAD_FAST 2 (c)
10 BINARY_MULTIPLY
11 RETURN_VALUE
可知,兩個(gè)函數(shù)分別都是先對(duì)a、b變量做引用的push stack操作,然后執(zhí)行相加,
緊接著對(duì)變量c做push stack操作,接著與a、b的和進(jìn)行相乘,最后返回結(jié)果
再次說(shuō)明lambda parameters: expression 等價(jià)于 def (parametes): return expression
lambda特點(diǎn)
lambda是一個(gè)表達(dá)式,而不是一個(gè)語(yǔ)句
lambda_expr ::= "lambda" [parameter_list]: expression
lambda是只有一行的簡(jiǎn)單表達(dá)式,并不能擴(kuò)展成一個(gè)多行的代碼塊
Python文檔說(shuō)到,lambda不能包含語(yǔ)句,這是因?yàn)镻ython的語(yǔ)法框架無(wú)法處理嵌套在表達(dá)式中的語(yǔ)句。lambda可以接收多個(gè)參數(shù),但只能有一個(gè)包含這些參數(shù)計(jì)算的表達(dá)式。這意味著lambda中不會(huì)含有if... elif... else 或者 try... except等語(yǔ)句,lambda的設(shè)計(jì)主要是用來(lái)計(jì)算簡(jiǎn)單的任務(wù)。
lambda使用場(chǎng)景
在平時(shí)的開(kāi)發(fā)過(guò)程中,使用def而非lambda定義函數(shù)足夠完成各種功能的開(kāi)發(fā),但適當(dāng)?shù)氖褂胠ambda能夠讓我們的代碼更加簡(jiǎn)潔明了。那在什么樣的場(chǎng)景下推薦使用lambda呢?
一個(gè)小的功能函數(shù),只需要一行就能完成,且只會(huì)被調(diào)用一次
比如要對(duì)整數(shù)列表中的所有元素添加存儲(chǔ)單位的操作:
>>> def add_unit(num):
return '{}mb'.format(num)
>>> map(add_unit, range(5))
['0mb', '1mb', '2mb', '3mb', '4mb']
>>> map(lambda n: '{}mb'.format(n), range(5))
['0mb', '1mb', '2mb', '3mb', '4mb']
# 可見(jiàn),使用lambda的代碼更加簡(jiǎn)潔
編程中與高階函數(shù)聯(lián)合使用
實(shí)際開(kāi)發(fā)中,lambda更多的是與map、filter、reduce等高階函數(shù)搭配使用,因?yàn)檫@些函數(shù)中需要接收函數(shù)對(duì)象作為參數(shù),使用lambda達(dá)到了既定義函數(shù)又傳遞函數(shù)的目的,比如map(lambda x: x ** 2, range(5)),這里的lambda x: x ** 2先定義函數(shù),然后將此函數(shù)對(duì)象作為參數(shù)傳遞給map;如果是def則需要首先在外部定義這個(gè)函數(shù),而不能在map函數(shù)中直接通過(guò)def來(lái)定義,map(def..., range(5)),Python不允許這樣的語(yǔ)法。
lambda注意點(diǎn)
上面講到lambda的特點(diǎn)是只能有一個(gè)表達(dá)式,使用lambda的目的是為了讓代碼更加簡(jiǎn)潔明了,所以在使用過(guò)程中需要注意以下幾點(diǎn):
lambda專注完成簡(jiǎn)單的任務(wù),其表達(dá)式要易讀
不推薦在編碼中為了使用lambda而將表達(dá)式寫(xiě)的很繁瑣,就像Python文檔中說(shuō)到的reduce(lambda a, b: (0, a[1] + b[1]), items)[1]這個(gè)表達(dá)式,你能很快看出lambda函數(shù)的意圖嗎?答案是不能,所以對(duì)于復(fù)雜點(diǎn)的邏輯,最好不要用lambda
程序中多處都會(huì)用一個(gè)小函數(shù)功能,則建議用def定義這個(gè)小函數(shù)
對(duì)列表中的數(shù)字求平方,lambda表達(dá)式為lambda n: n ** 2,簡(jiǎn)單,易讀。如果程序中不止一處需要對(duì)數(shù)字求平方,若均使用lambda,則顯得代碼冗余
開(kāi)發(fā)中先def,后lambda
在實(shí)際開(kāi)發(fā)過(guò)程中,我傾向于把不管什么類型的函數(shù)均先通過(guò)def來(lái)定義,等程序開(kāi)發(fā)接近尾聲的時(shí)候,再依據(jù)簡(jiǎn)單任務(wù)、只用一次的原則看看把哪些def定義的函數(shù)可以替換成lambda匿名函數(shù),并寫(xiě)上必要的注釋
謹(jǐn)慎使用lambda
其實(shí)從Python文檔函數(shù)式編程的說(shuō)明部分可以了解到,文檔作者傾向于不使用lambda,原因就是lambda的單個(gè)表達(dá)式、無(wú)法擴(kuò)展多行代碼塊等自身的功能限制。所以我們一定要秉持小函數(shù)、簡(jiǎn)單任務(wù)、只用一次的原則來(lái)決定是否要用lambda,千萬(wàn)別寫(xiě)出了大家半天都看不太明白的lambda表達(dá)式
總結(jié)
花了一些時(shí)間,重新梳理了自己對(duì)lambda的認(rèn)識(shí),Python文檔常把lambda與小函數(shù)綁定在一起,因此我們對(duì)lambda的使用要依據(jù)小函數(shù)、簡(jiǎn)單任務(wù)、只用一次的原則。引入lambda是為了讓代碼更加簡(jiǎn)潔明了,萬(wàn)不可為了少寫(xiě)代碼、為了簡(jiǎn)潔而寫(xiě)出了很復(fù)雜的表達(dá)式,簡(jiǎn)潔明了與易讀都是需要的。以上就是我對(duì)lambda的認(rèn)識(shí),您有什么不一樣的看法嗎?歡迎一起交流。
引用
總結(jié)
以上是生活随笔為你收集整理的python lambda 判断_Python lambda的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 什么是IP Routing
- 下一篇: websocket python爬虫_p