一道面試題讓我重新學(xué)了一遍匿名函數(shù)
回復(fù)“書籍”即可獲贈(zèng)Python從入門到進(jìn)階共10本電子書
前言
首先祝各位節(jié)日快樂,不管有沒有npy,大家還是要快樂,過(guò)節(jié)也不能停止學(xué)習(xí)。上一篇文章群友問(wèn)了道3行代碼的python面試題,我懵逼了...給大家說(shuō)了一道Python面試題,很多小伙伴都拍了自己大腿,我竟然這么無(wú)知。

不要慌,今天kuls帶大家來(lái)學(xué)習(xí)學(xué)習(xí)匿名函數(shù)。首先看這個(gè)名字就知道這個(gè)函數(shù)沒有名字(禁止套娃),那它是個(gè)啥玩意?
匿名函數(shù)
大家不慌,其實(shí)匿名函數(shù)只有一行代碼:
lambda?argument1,?argument2,...?argumentN?:?expression

先直接給大家看一個(gè)小案例,我們?cè)賮?lái)解釋是啥意思:
f?=?lambda?a,?b,?c:?a+b+c
print(f(6,?6,?6))
把上面的函數(shù)寫成普通函數(shù):
def?f(a,?b,?c):
????return?a+b+c
print(f(6,?6,?6))
相信大家看到了它的普通函數(shù)就知道是啥意思了。我們看到上面的代碼,在匿名函數(shù)中我們使用lambda關(guān)鍵字來(lái)表示匿名函數(shù)。
冒號(hào)之前是我們的變量,冒號(hào)之后是我們的表達(dá)式。
大家可能發(fā)現(xiàn)我們lambda表達(dá)式中是沒有return語(yǔ)句的,因?yàn)閘ambda不需要它來(lái)返回,表達(dá)式本身結(jié)果就是返回值。
跟函數(shù)的區(qū)別
既然說(shuō)lambda是屬于表達(dá)式,那么它必定跟函數(shù)是有區(qū)別的,舉一個(gè)簡(jiǎn)單的例子:表達(dá)式可以在list中使用,而函數(shù)則不行。
[(lambda?x:x**2)(x)?for?x?in?range(10)]
輸出結(jié)果:
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
有一部分小伙伴可能不太懂上面的for循環(huán)語(yǔ)句,我在這里給大家分析一下:
[(lambda?x:x**2)(x)?for?x?in?range(10)]
這個(gè)lambda表達(dá)式在list中,這個(gè)不用多說(shuō),但是后面那個(gè)(x)是啥意思呢?我們首先把它去掉打印一下:
[(lambda?x:x**2)?for?x?in?range(10)]
輸出結(jié)果:
[<function?.?at?0x1014bbf80>,?<function?.?at?0x10146dcb0>,?<function?.?at?0x101465dd0>,?<function?.?at?0x1014b3dd0>,?<function?.?at?0x1014b3c20>,?<function?.?at?0x1014b3d40>,?<function?.?at?0x1014b3b90>,?<function?.?at?0x1014b3b00>,?<function?.?at?0x1014b3cb0>,?<function?.?at?0x1014818c0>]
我們可以看到返回的是函數(shù)地址,這里也就說(shuō)明此時(shí)的列表中存儲(chǔ)的只是內(nèi)存地址,并沒有真正的調(diào)用lambda函數(shù)進(jìn)行計(jì)算。這樣也就說(shuō)明了(x)的作用就是類似于函數(shù)中的參數(shù),將for循環(huán)中的x值傳給lambda表達(dá)式,然后進(jìn)行計(jì)算。
除此之外,lambda表達(dá)式還能作為函數(shù)的參數(shù),這里我就不去展示了。
一些有意思的匿名函數(shù)
這里的一些匿名函數(shù),我也是從網(wǎng)上摘取過(guò)來(lái)的,大家可以看看這些匿名函數(shù)。
無(wú)參匿名函數(shù):
t?=?lambda?:?True?#分號(hào)前無(wú)任何參數(shù)
t()
True
等價(jià)于下面的def定義的函數(shù)
def?func():?return?True
func()
True
參數(shù)存在默認(rèn)值
f2?=?lambda?x,y=3:?x*y
print(f2(2))
結(jié)果:
6
表達(dá)式后傳參
(lambda?x,y:?x?if?x>?y?else?y)(103,102)
輸出:
103
由于篇幅原因這里就舉幾個(gè)這樣的例子,需要看更多有意思的匿名函數(shù),大家可以自行百度。
匿名函數(shù)的好處
我們接觸了匿名函數(shù),并且知道它的基本使用。那這玩意到底有啥用?
其實(shí)大家能夠很直觀的就能夠看到,使用匿名函數(shù)減少了我們的代碼量,大家不要忽略這一點(diǎn),認(rèn)為它并沒有給我們省很多的代碼量,當(dāng)你做的項(xiàng)目足夠大時(shí),你會(huì)恨不得少一個(gè)字母。
函數(shù)式編程
說(shuō)到了lambda表達(dá)式,我們不得不提Python的函數(shù)式編程。什么是函數(shù)式編程?指代碼中每一塊都是不可變的,都由純函數(shù)的形式組成。這里的純函數(shù),是指函數(shù)本身相互獨(dú)立、互不影響,對(duì)于相同的輸入,總會(huì)有相同的輸出,沒有任何副作用。
大家可能還是不太理解什么是函數(shù)式編程,到底啥不能改變,我們舉個(gè)簡(jiǎn)單的例子:
l?=?[1,2,3]
def?a(l):
????for?i?in?range(0,len(l)):
????????l[i]?+=?10
????return?l
print(a(l))
大家可以看到,上面我們將列表l中的值全部加10,這樣列表中的值發(fā)生了改變,也就是說(shuō)我們函數(shù)里面發(fā)生了變化,所以我們不能稱之為純函數(shù)。那么純函數(shù)的形式怎么寫呢?
def?b(l):
????new_l?=?[]
????for?item?in?l:
????????new_l.append(item+10)
????return?new_l
print(b(l))
我們需要在里面重新創(chuàng)建一個(gè)新的list。
為什么要說(shuō)函數(shù)式編程呢?因?yàn)樵趐ython中提供了幾個(gè)函數(shù)來(lái)支持函數(shù)式編程:
map(function, iterable)
r?=?map(lambda?x:x**2,[1,2,3])
list(r)
結(jié)果:
[1, 4, 9]
map函數(shù)式python自帶的函數(shù),map()傳入的第一個(gè)參數(shù)是f,即函數(shù)對(duì)象本身。由于結(jié)果r是一個(gè)Iterator,Iterator是惰性序列,因此通過(guò)list()函數(shù)讓它把整個(gè)序列都計(jì)算出來(lái)并返回一個(gè)list。
fliter(function, iterable)
其實(shí)它和上面的map非常的相似,同樣是傳入函數(shù)以及iterable。fliter函數(shù)會(huì)對(duì)iterable中的每一個(gè)元素進(jìn)行function的判斷,并且返回True或者Flase,最后會(huì)把True的元素組成一個(gè)列表返回。
>>>?l?=?[1,?2,?3,?4,?5]
>>>?new_list?=?filter(lambda?x:?x?%?2?==?0,?l)?
>>>?list(new_list)
結(jié)果:
[2, 4]reduce(function, iterable)
reduce(function, iterable)表示對(duì)某個(gè)集合做function函數(shù)的累積。
直接給大家看下代碼
>>>?from?functools?import?reduce
>>>?l?=?[1,2,3]
>>>?r?=?reduce(lambda?x,y?:x*y,l)
>>>?print(r)
結(jié)果:
6
總結(jié)
總算寫完了,雖然匿名函數(shù)在平常的開發(fā)中比較少見,但是它是一個(gè)開發(fā)人員必不可少的知識(shí)。從之前的面試題我們也可以看到,匿名函數(shù)的考察也是會(huì)有的。文章純手敲,如果里面有錯(cuò)誤,還麻煩聯(lián)系我微信(下面有二維碼)。
原創(chuàng)不易,希望大家多多點(diǎn)再看!在看數(shù)超過(guò)30,馬上出下一篇干貨文!!!

本文部分知識(shí)參考了:
https://blog.csdn.net/weixin_34007291/article/details/88755406
-------------------?End?-------------------
往期精彩文章推薦:
如何利用Scrapy爬蟲框架抓取網(wǎng)頁(yè)全部文章信息(中篇)
如何利用Scrapy爬蟲框架抓取網(wǎng)頁(yè)全部文章信息(上篇)
關(guān)于Scrapy爬蟲框架中meta參數(shù)的使用示例演示(上)
關(guān)于Scrapy爬蟲框架中meta參數(shù)的使用示例演示(下)

歡迎大家點(diǎn)贊,留言,轉(zhuǎn)發(fā),轉(zhuǎn)載,感謝大家的相伴與支持
想加入Python學(xué)習(xí)群請(qǐng)?jiān)诤笈_(tái)回復(fù)【入群】
萬(wàn)水千山總是情,點(diǎn)個(gè)【在看】行不行
/今日留言主題/
隨便說(shuō)一兩句吧~~
