答案

創(chuàng)新互聯(lián)公司服務(wù)項目包括五峰網(wǎng)站建設(shè)、五峰網(wǎng)站制作、五峰網(wǎng)頁制作以及五峰網(wǎng)絡(luò)營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢、行業(yè)經(jīng)驗、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,五峰網(wǎng)站推廣取得了明顯的社會效益與經(jīng)濟效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到五峰省份的部分城市,未來相信會繼續(xù)擴大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!
首先函數(shù)柯里化因為參數(shù)固定,使用vars數(shù)組保存每次傳進來的參數(shù),然后判斷fn的參數(shù)個數(shù),如果fn參數(shù)個數(shù)正好等于vars數(shù)組中保存的個數(shù),那么執(zhí)行fn,否則遞歸一次,返回curried函數(shù),繼續(xù)等待輸入。這里外層curry 函數(shù)只會執(zhí)行一次便會被剝離,之后add會變成curried的一個引用,同時curried可以閉包引用外層的vars,使得每次傳入的參數(shù)可以長久保存。
參考上面網(wǎng)上優(yōu)秀答案的思路,寫出這個不定參數(shù)處理add函數(shù),...args可以接受不定參數(shù),由于題目二中并沒有題目一中 const add = curry((a, b ,c ,d) = a + b + c +d) 函數(shù)劫持的過程,所以不能直接返回函數(shù)定義,而是要返回一個執(zhí)行完的函數(shù)curried(...args),同時在curried中再返回一個函數(shù)定義curried,這樣就可以把函數(shù)連接起來了。由于參數(shù)不定,這里對每次傳入的參數(shù)都要進行執(zhí)行處理,執(zhí)行方法是利用函數(shù)的隱式轉(zhuǎn)換,當(dāng)函數(shù)執(zhí)行結(jié)束時會有一個toString的操作,來使函數(shù)能參與其他的運算,這里我們將toString從新定義,返回vars中的累加值,從而實現(xiàn)add運算。
通過上面的定義可以看出,柯里化是一個函數(shù)返回另一個函數(shù),這是一個典型的閉包,它封裝了一部分不變的內(nèi)容,然后去處理其他可變的數(shù)據(jù)
例如我們在使用ajax的時候url是不變的,但是傳遞的參數(shù)不同將返回不同的數(shù)據(jù),那么我們就可以把url封裝到一個函數(shù)里然后返回一個帶參數(shù)的函數(shù),通過返回的函數(shù)去處理不同參數(shù)的情況
上面的兩個請求參數(shù)不同,但是請求的地址url是固定不變的。這就是柯里化,將不變的參數(shù)通過閉包的形式封裝起來,然后去處理可變的參數(shù)
lodash中有一個柯里化方法 curry 。舉個官網(wǎng)的例子:
具體用法官網(wǎng)說明很清楚我就不再贅述了。
當(dāng)然是函數(shù)式那一套黑魔法啦,且聽我細(xì)細(xì)道來。
lambda表達式
也就是匿名函數(shù)。
用法:lambda 參數(shù)列表 : 返回值
例:
+1函數(shù)
f=lambda x:x+1
max函數(shù)(條件語句的寫法如下)
f_max=lambda x,y:x if xy else y
上述定義的函數(shù)與用def定義的函數(shù)沒有區(qū)別,而且左邊的f=在某些情況下并不是必要的。
filter,map,reduce
filter函數(shù)接受兩個參數(shù),第一個是過濾函數(shù),第二個是可遍歷的對象,用于選擇出所有滿足過濾條件的元素,不同版本的filter的返回值稍有區(qū)別,我用的是python3.5,filter返回的是經(jīng)過過濾的可遍歷對象。
例:
去除小寫字母
s=filter(lambda x:not str(x).islower(),"asdasfAsfBsdfC")
for ch in s:
print(ch)
map函數(shù)接受的參數(shù)類型與filter類似,它用于把函數(shù)作用于可遍歷對象的每一個元素。類似于數(shù)學(xué)中映射的概念。
例:
求y=2x+1(偷偷用了一下range函數(shù)生成定義域)
s=map(lambda x:2*x+1,range(6))
for x in s:
print(x)
reduce函數(shù)對每個元素作累計操作,它接受的第一個參數(shù)必須是有兩個參數(shù)的函數(shù)。
例:
求和
from functools import reduce
s=reduce(lambda x,y:x+y,range(1,6))
print(s)
求乘積(第三個可選參數(shù)表示累計變量的初值)
from functools import reduce
s=reduce(lambda x,y:x*y,range(1,6),1)
print(s)
柯里化(curry)函數(shù)
如果一個函數(shù)需要2個參數(shù),而你只傳入一個參數(shù),那么你就可以得到一個柯里化的函數(shù),這是函數(shù)式編程語言的重要特性之一,遺憾的是,python并不能在語法層面支持柯里化調(diào)用,但它在庫中提供了接口。
例:
*3函數(shù)
f_mul=lambda x,y:x*y
from functools import partial
mul3=partial(f_mul,3)
print(mul3(1))
print(mul3(6))
打包與解包
有點類似于函數(shù)式中的模式匹配,略牽強。
t=(1,2,3)
x,y,z=t
列表生成式
這個也有點牽強,不知道嚴(yán)格意義上講屬不屬于函數(shù)式風(fēng)格。
例:生成奇數(shù)序列
l=[2*x+1 for x in range(10)]
for i in l:
print(i)
最后來一個彩蛋(以前某答主提到的用調(diào)分函數(shù)來美顏的算法,忘了出處了,侵刪)
from PIL import Image
from math import sqrt
im = Image.open("a.jpg")
ret= im.convert(mode="RGB")
ret = ret.point(lambda x:sqrt(x)*sqrt(255))
ret.save("b.jpg")
答案中的方法使用函數(shù)裝飾器實現(xiàn)
def currying(func, n=None):
n = n or func.__code__.co_argcount
def merge(*head):
? k = len(head)
? if k == n:
? ? ? return func(*head)
? elif k n:
? ? ? return currying(lambda *tail: func(*(head + tail)), n - k)
? elif k n:
? ? ? raise TypeError('Too many arguments:', head)
return merge
裝飾器代碼
通過對目標(biāo)函數(shù)進行裝飾,實現(xiàn)目標(biāo)函數(shù)柯里化,原理是對目標(biāo)函數(shù)的參數(shù)進行計數(shù),當(dāng)接收參數(shù)達到指定個數(shù)時進行計算,否則保存已有的參數(shù),其中 currying 函數(shù)的第一個參數(shù)是目標(biāo)函數(shù),第二個參數(shù)是接收的參數(shù)數(shù)量,默認(rèn)值為目標(biāo)函數(shù)的參數(shù)個數(shù)。
示例代碼
如上圖代碼所示,add3 函數(shù)使用 currying 函數(shù)裝飾,即可實現(xiàn)柯里化
運行結(jié)果
本文題目:Python函數(shù)柯里化 python 柯里化
文章出自:http://chinadenli.net/article12/highgc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站建設(shè)、品牌網(wǎng)站設(shè)計、網(wǎng)站制作、網(wǎng)站設(shè)計、、定制開發(fā)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)