接收函數爲參數,或者把函數做爲結果返回的函數爲高階函數。html
要求:仿照內建函數sorted,自行實現一個sort函數。內建函數sorted函數是返回一個新的列表,能夠設置升序或降序,也能夠設置一個排序的函數,自定義的sort函數也要實現這個功能。編程
sort函數實現思路:新建一個列表,遍歷原列表,和新列表的值一次比較決定如何插入到新列表中。閉包
sort函數版本一的實現,代碼以下:app
1 def sort(iterable): 2 ret = [] 3 for x in iterable: 4 for i, y in enumerate(ret): 5 if x > y: # 找到比ret中大的位置上的數插入相應位置,降序排序 6 ret.insert(i, x) 7 break 8 else: # 不大於,說明x在ret中是最小的,直接將其追加至ret後 9 ret.append(x) 10 return ret 11 12 if __name__ == '__main__': 13 lst = [1,2,3,4,5,6,7,8] 14 print(sort(lst))
上述代碼只能實現的,升序的排列方式,那麼如今想經過一個參數來控制排列的方式,該如何實現呢?看以下代碼:ide
1 def sort(iterable, reverse=False): 2 ret = [] 3 for x in iterable: 4 for i, y in enumerate(ret): 5 flag = x > y if reverse else x < y # 默認排序方式爲升序 6 if flag: # 找到比ret中大的位置上的數插入相應位置,降序排序 7 ret.insert(i, x) 8 break 9 else: # 不大於,說明x在ret中是最小的,直接將其追加至ret後 10 ret.append(x) 11 return ret
經過對reverse參數的boole值進行判斷,看使用降序仍是升序,那麼能不能將對x,y大小的判斷的功能抽象出來,做爲一個排序的函數傳給sort函數?看以下代碼:函數式編程
1 def comparator(x, y): 2 if x > y: 3 return False 4 else: 5 return True 6 7 def sort(iterable, reverse=False, key=None): 8 ret = [] 9 for x in iterable: 10 for i, y in enumerate(ret): 11 flag = key(x, y) if reverse else not key(x, y) 12 if flag: # 找到比ret中大的位置上的數插入相應位置,默認降序排序 13 ret.insert(i, x) 14 break 15 else: # 不大於,說明x在ret中是最小的,直接將其追加至ret後 16 ret.append(x) 17 return ret
該代碼中在調用sort函數,每次都得傳入一個函數才能實現排序,那麼能不能用一個函數的表達式做爲一個默認值參數進行傳入呢?這就要用到匿名函數,代碼以下:函數
1 def sort(iterable, reverse=False, key=lambda a,b:a>b): 2 ret = [] 3 for x in iterable: 4 for i, y in enumerate(ret): 5 flag = key(x, y) if not reverse else not key(x, y) 6 if flag: # 找到比ret中大的位置上的數插入相應位置,默認降序排序 7 ret.insert(i, x) 8 break 9 else: # 不大於,說明x在ret中是最小的,直接將其追加至ret後 10 ret.append(x) 11 return ret
一步一步的將代碼實現到這,已經將sort函數從最初實現的簡單排序,改爲最終的能夠設置升序和排序,以及設置排序的規則的函數。這樣就將sort函數改爲了一個高階函數。學習
sorted(iterable[, key][, reverse]),內置函數sorted函數中可選的key參數用於提供一個函數,它會應用到各個元素上進行排序。例如,若是想根據單詞的長度進行排序,只需將len函數傳給key參數,以下示例:spa
任何單參數函數都能做爲key參數的值,再好比實現:將每一個單詞的字母反轉後,在對其進行排序。實現以下:3d
在函數式編程中,Python 3中經常使用的高階函數還有,map、filter。
filter(function, iterable),過濾可迭代對象的元素,返回一個迭代器。function是一個具備單參數的函數,返回bool值。
1 list(filter(lambda x: x%3==0, [1,9,55,150,-3,78,28,123])) # 過濾出數列中能被3整除的數字
map(function, *iterables),對多個可迭代對象的元素按照指定的函數進行映射,返回一個迭代器。
list(map(lambda x:2*x+1, range(5))) dict(map(lambda x: (x%5,x) , range(500)))
在Python 3中,map和filter返回生成器(一種迭代器),所以如今它們的直接替代品是列表推導式和生成器表達式。
柯里化指的是將原來接收兩個參數的函數變成新的接收一個參數的函數的過程。新的函數返回一個以原有第二個參數爲參數的函數。其形式至關於將z = f(x, y)轉換成z = f(x)(y)的形式。舉例:
1 # 將加法函數柯里化 2 def add(x, y): 3 return x + y 4 5 # 柯里化 6 def add(x): 7 def inc(y): 8 return x + y 9 return inc 10 11 foo = add(2) 12 print(foo(3)) 13 # 至關於 14 print(add(2)(3))
經過柯里化的過程可知,在柯里化時使用嵌套函數就能夠將函數轉換成柯里化函數。
從前面的閉包,以及如今的高階函數以及函數的柯里化,這些都是Python裝飾器的基礎,有了這些基礎,就能夠學習Python中的裝飾器。
原文出處:https://www.cnblogs.com/dabric/p/11691824.html