python進(jìn)階-函數(shù)式編程庫toolz用法介紹-part2

??在第一部分簡單介紹了python的函數(shù)式編程基本方法后,從這部分開始將開始更深入的學(xué)習(xí)toolz的使用方法。話不多說,下面開始上示例代碼。
??將上一部分的函數(shù)拿來繼續(xù)用

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

def mul(x, y):
    return x * y

def lesser(x, y):
    if x < y:
        return x
    else:
        return y

def greater(x, y):
    if x > y:
        return x
    else:
        return y

??首先是accumulate的用法,功能類似于numpy的累加,不過操作(加、乘或其他計(jì)算)具體由傳入的第一個(gè)參數(shù)來決定;又可以看出和reduce相近,只不過reduce只返回最后的結(jié)果

import numpy as np
X[X>=10].cumsum()
# >>>array([ 10,  21,  33,  46,  60,  75,  91, 108, 126, 145], dtype=int32)

data = range(10, 20)
list(accumulate(add, data))
# >>>[10, 21, 33, 46, 60, 75, 91, 108, 126, 145]

from functools import reduce
reduce(add,data)
# >>>145

??繼續(xù)來看map、reduce、accumulate的更靈活的一些用法,

data1 = [1, 2, 3, 4, 5]
data2 = [10, 20, 30, 40, 50]
list(map(add, data1, data2))
# >>>[11, 22, 33, 44, 55]

reduce(lesser, [5, 3, 2, 7, 3], 999999999) # 注意第三個(gè)參數(shù)為初值
# >>> 2
reduce(lesser, [5, 3, 2, 7, 3], 1)
# >>> 1

list(accumulate(lesser, [5, 3, 2, 7, 3]))
# >>> [5, 3, 2, 2, 2]

??可以看出map、reduceaccumulate的第一個(gè)參數(shù)需要傳入一個(gè)兩個(gè)參數(shù)的函數(shù)(類似于雙目運(yùn)算符)。
??到現(xiàn)在為止,熱身活動(dòng)已經(jīng)結(jié)束了,開始介紹下面重要的一個(gè)概念,函數(shù)的柯里化(Currying,中文翻譯還是有些怪,看英文有可能突然想到投3分的庫里啊)。首先介紹python中的幾種處理高階函數(shù)(higher order function)的方式,高階函數(shù)可以簡單理解為函數(shù)的函數(shù),即函數(shù)可以當(dāng)做變量傳來傳去,從而達(dá)到更靈活的用法。

#方式1 普通函數(shù)
def cumsum(data):
    return accumulate(add, data)
#方式2 匿名函數(shù)
cumsum = lambda data: accumulate(add, data)
#方式3 偏函數(shù)
from functools import partial
cumsum = partial(accumulate, add)
#三種方式都是下面一個(gè)結(jié)果
list(cumsum(data))
# >>>[10, 21, 33, 46, 60, 75, 91, 108, 126, 145]

??我們用高階函數(shù)的方式實(shí)現(xiàn)了一個(gè)輸出每步累加值的函數(shù)cumsum,除了普通函數(shù)的方式外,另外兩種方式個(gè)人感覺都還算pythonic,選哪種看個(gè)人喜好了。
??同樣的功能,更函數(shù)式的方式,下面輪到神射手curry出場(chǎng)了!

from toolz import curry
mul_cur = curry(mul)
mul_cur(2)  # 傳入?yún)?shù)后返回一個(gè)函數(shù),然后就剩下一個(gè)參數(shù)可傳了
# >>> <function mul at 0x00000000072A1EA0>
mul_cur(2)(3)
# >>> mul_cur(2)(3)

# 方式4 currying的方式
accumulate = curry(accumulate)
cumsum = accumulate(add)

??用斐波那契函數(shù)的例子來說明一下稍微復(fù)雜一點(diǎn)的情況,生成斐波那契數(shù)列的前10個(gè)數(shù)字,但是又不想(或者不能)改變fib函數(shù)的前提下(雖然我知道這樣執(zhí)行效率低),通過curry來得到了一個(gè)新的函數(shù),相比于直接用列表展開或者每次都用map去做的話,肯定是更加方便快捷,并且通過新的函數(shù)名提高了程序的可讀性。

def fib(n):
    a, b = 0, 1
    for i in range(n):
        a, b = b, a + b
    return b
fib(9)
# >>> 55
map = curry(map)
fibMany = map(fib)
list(fibMany(range(10)))
# >>> [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

??最后,告訴大家其實(shí)沒必要每次都用curry去“包裹”一次maptoolz里面做好準(zhǔn)備工作,提供了相關(guān)的柯里化好的函數(shù)。

from toolz.curried import map, accumulate, reduce, filter  
# 函數(shù)很多就不一一列舉了, 這些都等價(jià)于下面手動(dòng)柯里化
from toolz import map, curry
map = curry(map)

??未完待續(xù) ...

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

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