Python 函數(shù)式編程

Python 提供 3 種內(nèi)建函數(shù)和 lambda 表達(dá)式等來(lái)支持函數(shù)式編程。

匿名函數(shù)

Python 允許用 lambda 關(guān)鍵字創(chuàng)造匿名函數(shù)耙替。匿名顧名思義就是沒有名字,即不需要以標(biāo)準(zhǔn)的方式來(lái)聲明,比如說(shuō),使用 def 加函數(shù)名來(lái)聲明沼沈。一個(gè)完整的 lambda “語(yǔ)句”代表了一個(gè)表達(dá)式,這個(gè)表達(dá)式的定義體必須和聲明放在同一行币厕。語(yǔ)法如下:

lambda [arg1[, arg2, ... argN]]: expression

參數(shù)是可選的列另,如果使用參數(shù)的話,參數(shù)通常也會(huì)出現(xiàn)在表達(dá)式中旦装。

注意:lambda 表達(dá)式返回可調(diào)用的函數(shù)對(duì)象页衙。其實(shí) lambda 表達(dá)式本身就是一個(gè)函數(shù),這個(gè)函數(shù)定義了輸入(冒號(hào)左邊)和輸出(冒號(hào)右邊),只不過(guò)這個(gè)函數(shù)沒有名字店乐,但是我們可以把它賦給一個(gè)變量艰躺。

比如簡(jiǎn)單的加法函數(shù)。一般我們是這么寫的:

def add(x, y):
    return x+y

lambda 表達(dá)式這么寫:

lambda x, y : x + y

我們可以把 lambda x, y : x + y 賦值給 f 响巢,然后給 f 傳參數(shù):

>>> f = lambda x, y : x + y
>>> f
 at 0x10377f320>
>>> f(-10,8)
-2
>>> f(12, 100)
112
>>> f(-33, -22)
-55

可以看到描滔,f 確實(shí)是個(gè)函數(shù),可以接收兩個(gè)參數(shù)踪古,并返回這兩個(gè)參數(shù)的和,等價(jià)于上面的 add 函數(shù)券腔。

使用場(chǎng)景

1伏穆、函數(shù)式編程
2、閉包
簡(jiǎn)單粗暴地理解為閉包就是一個(gè)定義在函數(shù)內(nèi)部的函數(shù)纷纫,閉包使得變量即使脫離了該函數(shù)的作用域范圍也依然能被訪問到枕扫。

高階函數(shù)

高階函數(shù)英文叫 Higher-order function 。一般函數(shù)的輸入?yún)?shù)和返回值都只能是變量或常量辱魁,如果某個(gè)函數(shù)可以接收函數(shù)作為其輸入?yún)?shù)烟瞧,或者其返回值中包含函數(shù),那么該函數(shù)就是高階函數(shù)染簇。
Python 中有三個(gè)內(nèi)建的用來(lái)支持函數(shù)式編程的高階函數(shù)参滴,分別是 filter()map()reduce()锻弓。

filter()

filter(function, sequence) 返回一個(gè) sequence (序列)砾赔,返回的序列中包括了輸入序列中所有調(diào)用 function(item) 后返回值為 true 的元素。

舉個(gè)栗子:

>>> def f(x): return x % 3 == 0 or x % 5 == 0
...
>>> filter(f, range(2, 25))
[3, 5, 6, 9, 10, 12, 15, 18, 20, 21, 24]

因?yàn)?filter() 的輸入?yún)?shù)中包含函數(shù) f() 青灼,所以 filter() 是高階函數(shù)暴心。上面的例子中返回 2~24 中能被 3 或 5 整除的數(shù)組成的列表。

當(dāng)然杂拨,也可以使用匿名函數(shù) lambda 表達(dá)式實(shí)現(xiàn):

>>> filter(lambda x : x % 3 == 0 or x % 5 == 0, range(2, 25))
[3, 5, 6, 9, 10, 12, 15, 18, 20, 21, 24]

或者使用列表生成式:

>>> [x for x in range(2, 25) if x % 3 == 0 or x % 5 == 0]
[3, 5, 6, 9, 10, 12, 15, 18, 20, 21, 24]

map()

map() 與 filter() 相似专普,因?yàn)樗材芡ㄟ^(guò)函數(shù)來(lái)處理序列。map()將函數(shù)調(diào)用“映射”到序列的每個(gè)元素上弹沽,并返回一個(gè)含有所有返回值的列表檀夹。

舉個(gè)栗子:

>>> def cube(x): return x**3
...
>>> map(cube, range(1,11))

[1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]

上面的例子中,將 1~10 里的每個(gè)數(shù)分別調(diào)用 cube() 贷币,并將返回值(x 的 3 次方)放入列表中击胜。

lambda 表達(dá)式:

>>> map(lambda x : x**3, range(1, 11))
[1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]

列表生成式:

>>> [x**3 for x in range(1, 11)]
[1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]

注意:map() 也可以處理多個(gè)序列。

>>> map(lambda x, y: x + y, [1, 3, 5], [2, 4, 6])
[3, 7, 11]
>>> map(lambda x, y: (x+y, x-y), [1, 3, 5], [2, 4, 6])
[(3, -1), (7, -1), (11, -1)]
>>> map(None, [1, 3, 5], [2, 4, 6])
[(1, 2), (3, 4), (5, 6)]

reduce()

reduce(function, sequence) 返回一個(gè)單值役纹,它是這樣構(gòu)造的:首先以序列的前兩個(gè)元素調(diào)用函數(shù) function偶摔,再以返回值和第三個(gè)參數(shù)調(diào)用,依次執(zhí)行下去促脉。

例如辰斋,以下程序計(jì)算 0 到 5 的整數(shù)之和:

>>> def add(x, y): return x+y
...
>>> reduce(add, range(0, 5))
10

實(shí)際上 reduce() 執(zhí)行了如下的運(yùn)算:

((((0+1)+2)+3)+4)   ==>  10

lambda 表達(dá)式:

reduce(lambda x, y : x + y, range(0, 5))

偏函數(shù)

偏函數(shù)解決這樣的問題:如果我們有函數(shù)是多個(gè)參數(shù)的策州,我們希望能固定其中某幾個(gè)參數(shù)的值(類似于默認(rèn)值)。

舉個(gè)栗子:

int() 函數(shù)可以把字符串轉(zhuǎn)換為整數(shù)宫仗,當(dāng)僅傳入字符串時(shí)够挂,int() 函數(shù)默認(rèn)按十進(jìn)制轉(zhuǎn)換:

>>> int('11111')
11111

但 int() 函數(shù)還提供額外的 base 參數(shù)(默認(rèn)值為10) 。如果傳入 base 參數(shù)藕夫,就可以做 N 進(jìn)制的轉(zhuǎn)換:

>>> int('11111',8)
4681
>>> int('11111',base=16)
69905

假設(shè)要轉(zhuǎn)換大量的二進(jìn)制字符串孽糖,每次都傳入 int(x, base=2) 非常麻煩,于是毅贮,我們想到办悟,可以定義一個(gè) int2() 的函數(shù),默認(rèn)把 base=2 傳進(jìn)去:

def int2(x, base=2):
    return int(x, base)

這樣滩褥,我們就可以方便地轉(zhuǎn)換二進(jìn)制了:

>>> int2('1000000')
64
>>> int2('1010101')
85

functools.partial 就是幫助我們創(chuàng)建一個(gè)偏函數(shù)的病蛉,不需要我們自己定義 int2() ,可以直接使用下面的代碼創(chuàng)建一個(gè)新的函數(shù) int2 :

>>> import functools
>>> int2 = functools.partial(int, base=2)
>>> int2('11111')
31
>>> int2('10000')
16

總結(jié)一下瑰煎,functools.partial 的作用就是铺然,把一個(gè)函數(shù)的某些參數(shù)給固定住(也就是設(shè)置默認(rèn)值)酒甸,返回一個(gè)新的函數(shù)魄健,調(diào)用這個(gè)新函數(shù)會(huì)更簡(jiǎn)單。

需要注意的是烘挫,上面的新的 int2 函數(shù)诀艰,僅僅是把 base 參數(shù)重新設(shè)定默認(rèn)值為 2 ,但也可以在函數(shù)調(diào)用時(shí)傳入其他值:

>>> int2('11111',base=10)
11111
>>> int2('11111',base=8)
4681
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末饮六,一起剝皮案震驚了整個(gè)濱河市其垄,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌卤橄,老刑警劉巖绿满,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異窟扑,居然都是意外死亡喇颁,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門嚎货,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)橘霎,“玉大人,你說(shuō)我怎么就攤上這事殖属〗闳” “怎么了?”我有些...
    開封第一講書人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)外潜。 經(jīng)常有香客問我原环,道長(zhǎng),這世上最難降的妖魔是什么处窥? 我笑而不...
    開封第一講書人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任嘱吗,我火速辦了婚禮,結(jié)果婚禮上滔驾,老公的妹妹穿的比我還像新娘谒麦。我一直安慰自己,他們只是感情好哆致,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開白布弄匕。 她就那樣靜靜地躺著,像睡著了一般沽瞭。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上剩瓶,一...
    開封第一講書人閱讀 51,125評(píng)論 1 297
  • 那天驹溃,我揣著相機(jī)與錄音,去河邊找鬼延曙。 笑死豌鹤,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的枝缔。 我是一名探鬼主播布疙,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼愿卸!你這毒婦竟也來(lái)了灵临?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤趴荸,失蹤者是張志新(化名)和其女友劉穎儒溉,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體发钝,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡顿涣,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了酝豪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片涛碑。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖孵淘,靈堂內(nèi)的尸體忽然破棺而出蒲障,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布晌涕,位于F島的核電站滋捶,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏余黎。R本人自食惡果不足惜重窟,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望惧财。 院中可真熱鬧巡扇,春花似錦、人聲如沸垮衷。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)搀突。三九已至刀闷,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間仰迁,已是汗流浹背甸昏。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留徐许,地道東北人施蜜。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像雌隅,于是被迫代替她去往敵國(guó)和親翻默。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容