
函數式編程 (Functional Programming, FP) 是一種程式設計範式,它將電腦運算視為數學函數的計算,並避免改變狀態 (State) 和變異數據 (Mutable Data)。
雖然 Python 不是純函數式語言,但它提供了強大的 FP 工具,讓我們能寫出更簡潔、更優雅的資料處理流水線。
1. Lambda 函數:匿名函數
有時候我們只需要一個簡單的小函數,特地用 def 定義太麻煩了。這時可以使用 Lambda 表達式。
語法:lambda arguments: expression
# 傳統函數
def add(x, y):
return x + y
# Lambda 函數
add_lambda = lambda x, y: x + y
print(add_lambda(3, 5)) # 8
注意:Lambda 函數只能包含單一表達式,不能包含複雜的語局 (如
if...else區塊,但可以用三元運算子)。
2. FP 三劍客:Map, Filter, Reduce
這三個高階函數是處理序列數據的神器。
2.1 map():映射
對序列中的每個元素套用同一個函數。
nums = [1, 2, 3, 4]
# 將每個數字平方
squared = map(lambda x: x**2, nums)
# map 回傳的是 iterator,需轉為 list 才能看到結果
print(list(squared)) # [1, 4, 9, 16]
2.2 filter():過濾
透過一個判斷函數 (回傳 True/False) 來保留想要的元素。
nums = [1, 2, 3, 4, 5, 6]
# 只保留偶數
evens = filter(lambda x: x % 2 == 0, nums)
print(list(evens)) # [2, 4, 6]
2.3 reduce():歸約
將序列中的元素經過運算「縮減」為單一結果 (如累加、累乘)。注意:它被移到了 functools 模組中。
from functools import reduce
nums = [1, 2, 3, 4, 5]
# 計算累加:((((1+2)+3)+4)+5)
total = reduce(lambda x, y: x + y, nums)
print(total) # 15
3. Pythonic 最佳實踐:Comprehensions (推導式)
雖然 map 和 filter 很強大,但在 Python 社群中,我們通常更喜歡用 List Comprehension,因為它更易讀且通常更快。
轉換 Map
# Map
squares = list(map(lambda x: x**2, range(5)))
# List Comprehension (推薦!)
squares = [x**2 for x in range(5)]
轉換 Filter
# Filter
evens = list(filter(lambda x: x % 2 == 0, range(10)))
# List Comprehension (推薦!)
evens = [x for x in range(10) if x % 2 == 0]
結合 Map + Filter
# 取出偶數並平方
result = [x**2 for x in range(10) if x % 2 == 0]
這比嵌套的 map(filter(...)) 清爽多了!
4. 函數式編程的優點
- 無副作用 (No Side Effects):函式不依賴也不修改外部狀態,這使得程式碼更易於測試和並行化 (Parallelism)。
- 聲明式 (Declarative):告訴電腦「我要什麼」(例如:我要所有偶數的平方),而不是「怎麼做」(寫迴圈、判斷、添加…)。
- 簡潔 (Concise):減少樣板代碼。
5. 總結
雖然我們不需要像 Haskell 工程師那樣極端運用 FP,但適度在 Python 中使用 FP 技巧能大幅提升代碼品質。
本章重點回顧:
- Lambda: 隨用隨丟的匿名小函數。
- Higher-order Functions:
map,filter,reduce能對集合進行映射、過濾與歸約。 - List Comprehension: Python 中取代
map與filter的首選語法。
下一章,我們將學習如何處理文字資料的終極武器——正規表達式 (Regular Expressions)!
延伸閱讀: