Python科學(xué)計(jì)算——Functional Programming

函數(shù)式編程 (Functional Programming) 或者函數(shù)程序設(shè)計(jì),又稱泛函編程,是一種編程范型,它將計(jì)算機(jī)運(yùn)算視為數(shù)學(xué)上的函數(shù)計(jì)算,并且避免使用程序狀態(tài)以及易變對象。在Python中,函數(shù)式編程主要由幾個函數(shù)的使用構(gòu)成:partial( ), lambda( ), map( ), reduce( ), filter( )。

partial( )

在傳遞函數(shù)的時候,有時我們可能想部分地應(yīng)用函數(shù)來創(chuàng)建新函數(shù)。這種情況下,一個巧妙的方法就是利用 functools.partial 創(chuàng)建。

def exp(base,  power):
      return base ** power # 這是一個二元函數(shù)

如果我們想用上述的二元函數(shù)創(chuàng)建一個新的函數(shù) two_to_the: 它的輸入是一個冪次( power),輸出的是exp(2, power) 的結(jié)果。

def two_to_the(power):
    return exp(2,power)
print two_to_the(3) # 8

一種另辟蹊徑的方法是使用 functools.partial:

from functools import partial
two_to_the = partial(exp, 2)
print two_to_the(3) # 8

當(dāng)然,也可以指定參數(shù)的名字:

square_of = partial(exp, power=2)
print square_of(3) # 9

lambda( )

lambda( )主要用于定義“行內(nèi)函數(shù)”,有點(diǎn)像Matlab的“匿名函數(shù)”,具體的操作如下:

f = lambda x : x + 2 # 定義函數(shù) f(x)=x+2
g = lambda x, y : x + y # 定義函數(shù) g(x, y)=x+y

map( )

map( ) 函數(shù)用于逐一遍歷。例如我們有一個list a = [1, 2, 3, 4], 要給 a 中的每一個元素加2得到一個新的list,有兩種方式:

b = [i+2 for i in a] # list comprehension
b = map(lambda x : x+2, a) # map( )

當(dāng)然,如果對多個列表操作,可以對帶有多個參數(shù)的函數(shù)使用 map( ) :

products = map(lambda x, y : x * y, [1, 2], [3, 4]) # [1*3, 2*4] = [3, 8]

有了列表解析 (list comprehension) , 為什么還用 map( ) 函數(shù)呢?其實(shí),列表解析雖然代碼簡單,但本質(zhì)上還是 for 循環(huán)命令,而 Python 的 for 循環(huán)命令效率不高,而 map( ) 函數(shù)實(shí)現(xiàn)了相同的功能,并且效率更高,原則上,它的循環(huán)命令速度相當(dāng)于 C 語言。

reduce( )

和 map( ) 函數(shù)類似,但 map( ) 函數(shù)用于逐一遍歷,而 reduce( ) 函數(shù)用于遞歸計(jì)算

multiply = reduce(lambda x, y : x * y, [1, 2, 3, 4]) # 1 * 2 * 3 * 4 = 24

reduce( ) 結(jié)合了列表的兩個元素,它們的結(jié)果又結(jié)合列表的第3個元素,這個結(jié)果之后又結(jié)合了第4個元素,依次下去,直到得到一個單獨(dú)的結(jié)果。

def multiply(x, y):
    return x * y
list_product = partial(reduce, multiply) # 將函數(shù) multiply 作為參數(shù)傳給 reduce
x_product = list_product([1, 2, 3, 4])

上述的過程,同樣能夠?qū)崿F(xiàn)相應(yīng)的功能。

filter( )

顧名思義, filter( ) 是一個過濾器,用來篩選 list 中符合條件的元素,例如:

b = filter(lambda x : x > 5 and x < 8, range(10)) # [6, 7]

上述的 filter( ) 用列表解析可以寫作:

b = [i for i in range(10) if i > 5 and i < 8]

很明顯,filter( ) 做了列表解析中 if 的工作。

注:需要注意的是,列表解析并不比上述函數(shù)復(fù)雜,但我們使用函數(shù) partial( ), lambda( ), map( ), reduce( ), filter( ), 它們在兼顧簡潔和效率的同時也為列表解析提供了函數(shù)式替代方案。

Stay hungry, Stay foolish. -- Steve Jobs

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容