高階函數

      在〈高階函數〉中尚無留言

高階函數Higher-order function

函數的參數, 可以接收變數, 而函數就是變數, 那麼就可以把函數傳給另一個函數的參數

def math(f, x, y):
    if f==abs:
        return f(x)+f(y)
    else:
        return f(x, y)
print(math(abs, -10, 5))
print(math(pow, 2,10))

上面代碼中, 將abs傳入math函數中, 由math的 f 接收, 所以 f 就變成了abs() 的功能了.  若將pow傳入add, 那麼 f 就變成了pow() 的功能.

所以, 我們就可以定義, 假如有一個函數, 他的任何一個參數是用來接收其他的函數, 那麼這的函數就稱為高階函數, 比如上面所說的 math函數, 就是高階函數. 常見的系統高階函數有map, reduce, filter, sorted

map

Python有一個蠻好用的函數 – map. 此函數接收二個參數, 第一個參數為另一個函數名, 第二個參數為Iterable, 比如

r=map(f, [1,2,3,4,5])

如此就會把list裏的元素, 一個一個傳入f去計算, 然後回傳一個Generator給r, 所以再用list把Generator一個一個計算出來. 如果f 是計算x2, 就會傳回 1,4,9,16,25. 如果f 是str,  就會把 數字轉成字串

def f(x):
    return x*x
r=map(f, [1,2,3,4,5])
print(list(r))
r=map(str, [1,2,3,4,5])
print(list(r))
結果 :
[1, 4, 9, 16, 25]
['1', '2', '3', '4', '5']

map()即為高階函數, 它把運算規則抽象化, 不但可計算List裏面所有元素的x2值, 也可將List裏的元素全轉為字串, 當然還可以作其他的事, 只需將函數傳入即可.

reduce

reduce的語法及其定義如下

reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)

由上可知, reduce是先把x1, x2 傳給 f 計算, 再把結果與 x3 傳給 f 計算, 然後再把結果與 x4 傳給 f 計算

reduce的應用, 使用下面代碼說明, 可計算 1+2+3+…+100的值

m=list(range(1,101))
def f(x, y):
    return x+y;
print(reduce(f, m))

下面的代碼, 有一資料 data 為dict, 使用map將dict裏的元素全轉為數字, 再使用reduce將前位數*10加上後位數, 就可以轉成一大串的整數

from functools import reduce
data = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}
def toInt(dic):
    def fn(x, y):
        return x * 10 + y
    def stoi(s):
        return dic[s]
    return reduce(fn, map(stoi, dic))
print(toInt(data))
結果 : 
123456789

filter

語法如下

filter(fn, [x1, x2, x3, x4, x5])

演算法

將list裏的值依序傳入fn, 經fn計算後傳回True or False, 若傳回值為True, 則保留此元素, 若傳回值為False, 則刪除此元素

請注意, filter返回Iterator, 是惰性序列, 需使用list()函數返回list

下面的代碼可以將字串中的空格刪除掉. 請注意一下, 雖然Python不需宣告型別, 但還是得先宣告
tmp=”, 否則是無法使用的

def trim(s):
    if s==' ': return False
    else: return True
str="This is a Book"
tmp=''
for s in filter(trim, str):
    tmp+=s
print(tmp)

sorted

sorted為一排序函數, 傳入的參數為一List, 然後對List的元素作大小排序, 如下

print(sorted([10,-3,9,-22,15,80]))
結果 :
[-22, -3, 9, 10, 15, 80]

同時sorted亦為一高階函數, 可將另一函數傳入key變數, 如下

print(sorted([10,-3,9,-22,15,80], key=abs)) #轉成絕對值再排序, 但輸出結果是有正負數的
print(sorted(['monkey', 'Pig', 'cat', 'dog'], key=str.lower))//轉成小寫再排序, 但輸出是有大小寫的
結果 :
[-3, 9, 10, 15, -22, 80]
['cat', 'dog', 'monkey', 'Pig']

反向排序則加入第三個參數  reverse=True

print(sorted(['monkey', 'Pig', 'cat', 'dog'], key=str.lower, reverse=True))
結果 :
['Pig', 'monkey', 'dog', 'cat']

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *