從前面章節,我們知道 Python 函數是以對象的形式實現的,屬於 一等對象 ( first-class object )。根據程式語言理論,一等對象必須滿足以下條件:
Python 函數同時滿足這幾個條件,因而也被稱為 一等函數 。高階函數 則是指那些以函數為參數,或者將函數作為結果返回的函數。對高階函數稍加利用,便能玩出很多花樣來。本節從一些典型的案例入手,講解 Python 函數高級用法。合理應用函數式編程技巧,不僅能讓代碼更加簡潔優雅,還能提高開發效率和程序質量。
函數式編程技巧最適合用在數據處理場景,接下來以成績單計算為例,展開講解。原始數據如下:
scores = [
{
'name': '小雪',
'chinese': 90,
'math': 75,
'english': 85,
},
{
'name': '小明',
'chinese': 70,
'math': 95,
'english': 80,
},
{
'name': '小麗',
'chinese': 85,
'math': 85,
'english': 90,
},
{
'name': '小宇',
'chinese': 85,
'math': 95,
'english': 90,
},
{
'name': '小剛',
'chinese': 65,
'math': 70,
'english': 55,
},
{
'name': '小新',
'chinese': 85,
'math': 85,
'english': 80,
},
]
sorted排序是我們再熟悉不過的場景,如果待排序元素可以直接比較,調用 sorted 函數即可:
>>> numbers = [2, 8, 6, 9, 7, 0, 1, 7, 0, 3]
>>> sorted(numbers)
[0, 0, 1, 2, 3, 6, 7, 7, 8, 9]對比較複雜的數據進行排序,則需要一些額外的工作。假如語文老師想對語文成績進行排序,改如何進行呢?
sorted 支持指定一個自定義排序函數 key ,該函數以列表元素為參數,返回一個值決定該元素的次序。由於我們需要根據語文成績對元素進行排序,因此需要實現一個函數將語文成績提取出來作為比較基準:
def by_chinese(item):
return item['chinese']現在只需要將 by_chinese 函數作為 key 參數傳給 sorted 即可實現語文成績排序:
>>> for item in sorted(scores, key=by_chinese):
... print(item['name'], item['chinese'])
...
小剛 65
小明 70
小麗 85
小宇 85
小新 85
小雪 90自定義排序函數還可以控制升降序,如果需要按分數從高到底依次排序,可以返回成績的負數作為排序基準:
def by_chinese_desc(item):
return -item['chinese']>>> for item in sorted(scores, key=by_chinese_desc):
... print(item['name'], item['chinese'])
...
小雪 90
小麗 85
小宇 85
小新 85
小明 70
小剛 65當然了,通過 sorted 函數 reverse 參數控制升降序,是一個更好的編程習慣,邏輯更清晰:
>>> for item in sorted(scores, key=by_chinese, reverse=True):
... print(item['name'], item['chinese'])
...
小雪 90
小麗 85
小宇 85
小新 85
小明 70
小剛 65
lambda像 by_chinese 這樣直接返回結果的極簡函數,其實沒有必要大動幹戈,用 匿名函數 定義即可。Python 中的 lambda 關鍵字用於定義匿名函數,匿名函數只需給出參數列表以及一個表達式作為函數返回值:
這樣一來,by_chinese 這個自定義排序函數,可以這樣來定義:
by_chinese = lambda item: item['chinese']相應地,我們實現語文成績排序的代碼編程這樣子:
>>> for item in sorted(scores, key=lambda item: item['chinese']):
... print(item['name'], item['chinese'])
...
小剛 65
小明 70
小麗 85
小宇 85
小新 85
小雪 90數學老師來了,也只需要改動一點點,就能實現數學成績排序了:
>>> for item in sorted(scores, key=lambda item: item['math']):
... print(item['name'], item['math'])
...
小剛 70
小雪 75
小麗 85
小新 85
小明 95
小宇 95函數式程式語言一般都會提供 map 、 filter 以及 reduce 這 3 個高階函數,再複雜的數據統計處理任務都可以轉換成這些算子的組合。因此,不少大數據平臺,例如 Hadoop 等,都以 map 、 reduce 為基礎算子。
Python 內部也自帶了這幾個高階函數,那麼這幾個高階函數如何與基礎算子組合,才能迸發巨大威力呢?點擊「閱讀原文」,獲取更多詳情!