Python常用高階函數全面解析:通俗易懂的指南
一、什么是高階函數?
高階函數(Higher-order Function)是指能夠接受其他函數作為參數,或者將函數作為返回值的函數。在Python中,函數是一等公民,可以像普通變量一樣傳遞和使用。
簡單理解:高階函數就是把函數當玩具的函數——可以接收函數、可以返回函數、可以把函數傳來傳去。
二、Python五大常用高階函數
Python中最常用的高階函數有五個,它們都來自functools
模塊或內置函數:
高階函數 | 作用 | 返回值 | 常用場景 |
---|---|---|---|
map() | 對序列中每個元素應用函數 | 迭代器 | 數據轉換 |
filter() | 過濾序列中符合條件的元素 | 迭代器 | 數據篩選 |
reduce() | 累積計算序列元素 | 單個結果 | 聚合計算 |
sorted() | 排序序列 | 新列表 | 數據排序 |
裝飾器 | 修改或增強函數功能 | 包裝后的函數 | 功能擴展 |
下面我們逐個詳細講解。
1. map()函數:批量處理器
作用:
對可迭代對象的每個元素應用指定函數,返回一個包含所有結果的新迭代器(Python 3 中返回 map
對象,需轉為列表顯示)。
語法:
map(function, iterable, ...)
function
:處理函數(可以是內置函數、lambda 或自定義函數)iterable
:可迭代對象(如列表、元組)
示例:
① 對列表元素平方
nums = [1, 2, 3, 4]
squared = map(lambda x: x**2, nums)
print(list(squared)) # 輸出: [1, 4, 9, 16]
② 多參數函數處理
def add(a, b):return a + blist1 = [1, 2, 3]
list2 = [4, 5, 6]
result = map(add, list1, list2)
print(list(result)) # 輸出: [5, 7, 9]
特點:
- 不修改原數據,生成新結果
- 可同時處理多個可迭代對象(要求函數能接收對應數量的參數)
- 適合統一轉換場景(如類型轉換、數學運算)
map()工作原理:
原始序列: [1, 2, 3, 4]↓ map(函數)
新序列: [函數(1), 函數(2), 函數(3), 函數(4)]
2. filter()函數:數據過濾器
作用:
篩選可迭代對象中滿足條件的元素,返回一個包含所有符合條件元素的新迭代器(Python 3 中返回 filter
對象)。
語法:
filter(function, iterable)
function
:判斷函數(返回True
/False
,若為None
則直接過濾掉“假值”)iterable
:可迭代對象
示例:
① 篩選偶數
nums = [1, 2, 3, 4, 5]
evens = filter(lambda x: x % 2 == 0, nums)
print(list(evens)) # 輸出: [2, 4]
② 過濾空字符串
words = ["hello", "", "world", None, " "]
valid = filter(None, words) # 過濾掉 bool(value) 為 False 的元素
print(list(valid)) # 輸出: ['hello', 'world', ' ']
特點:
- 保留原元素,只做篩選
- 適合條件過濾場景(如數據清洗、有效性檢查)
filter()工作原理:
原始序列: [1, 2, 3, 4, 5, 6]↓ filter(條件函數)
新序列: [2, 4, 6] # 只保留使函數返回True的元素
3. reduce()函數:累積計算器
作用:
對可迭代對象中的元素進行累積計算,通過指定的二元函數從左到右依次處理元素,最終返回一個單一的累積結果。
語法:
from functools import reduce # Python 3 需從模塊導入reduce(function, iterable[, initializer])
function
:二元函數(接收兩個參數,返回一個結果)。iterable
:可迭代對象(如列表、元組)。initializer
(可選):初始值,若提供則作為第一個計算的左參數。
核心邏輯:
- 從可迭代對象中依次取出兩個元素,傳遞給
function
計算。 - 將計算結果與下一個元素繼續傳遞給
function
,直到所有元素處理完畢。 - 返回最終結果。
示例:
① 計算列表元素的乘積
from functools import reducenums = [1, 2, 3, 4]
product = reduce(lambda x, y: x * y, nums)
print(product) # 輸出: 24 (1 * 2 * 3 * 4)
② 拼接字符串(帶初始值)
words = ["Hello", "World", "!"]
sentence = reduce(lambda x, y: f"{x} {y}", words, "Say:")
print(sentence) # 輸出: "Say: Hello World !"
③ 模擬 sum()
功能
nums = [10, 20, 30]
total = reduce(lambda x, y: x + y, nums)
print(total) # 輸出: 60
特點:
- 必須導入
functools
(Python 3 中不再是內置函數)。 - 適合需要逐步累積的場景(如累加、累乘、最大值/最小值)。
- 可指定初始值(避免空列表報錯)。
reduce()工作原理:
初始值(可選) + 序列: [a, b, c, d]↓ reduce(函數)
計算過程: 函數(函數(函數(a, b), c), d)
4. sorted()函數:智能排序器
作用:
對可迭代對象進行排序,返回一個新的排序后的列表(原數據不變)。
語法:
sorted(iterable, *, key=None, reverse=False)
iterable
:可迭代對象(如列表、字典鍵、字符串)。key
:排序依據的函數(高階函數用法)。reverse
:是否降序(默認False
升序)。
核心邏輯:
- 根據
key
函數處理每個元素,生成排序依據的臨時值。 - 按臨時值比較排序。
- 返回排序后的新列表。
示例:
① 基本排序(數字/字符串)
nums = [3, 1, 4, 2]
print(sorted(nums)) # 輸出: [1, 2, 3, 4]
print(sorted(nums, reverse=True)) # 輸出: [4, 3, 2, 1]words = ["banana", "apple", "cherry"]
print(sorted(words)) # 按字母順序: ['apple', 'banana', 'cherry']
② 使用 key
自定義排序規則
# 按字符串長度排序
words = ["apple", "banana", "cherry"]
print(sorted(words, key=lambda x: len(x))) # 輸出: ['apple', 'banana', 'cherry']# 按字典的某個鍵排序
students = [{"name": "Alice", "age": 25},{"name": "Bob", "age": 20}
]
print(sorted(students, key=lambda x: x["age"]))
# 輸出: [{'name': 'Bob', 'age': 20}, {'name': 'Alice', 'age': 25}]
③ 多級排序(元組 key
)
# 先按長度,長度相同按字母逆序
words = ["apple", "banana", "cherry", "date"]
print(sorted(words, key=lambda x: (len(x), -ord(x[0]))))
# 輸出: ['date', 'apple', 'cherry', 'banana']
特點:
- 返回新列表,原數據不變(與
list.sort()
方法不同)。 key
參數支持復雜排序邏輯(高階函數核心用途)。- 支持所有可迭代對象(甚至生成器)。
sorted()關鍵參數:
key
:指定一個函數,這個函數會作用于每個元素,然后根據函數返回的結果進行排序reverse
:排序規則,True
降序,False
升序(默認)
5. 裝飾器:函數的化妝師
在 Python 中,裝飾器(Decorator) 是一種高階函數,它的核心作用是在不修改原函數或類代碼的前提下,動態地增強或修改其功能。裝飾器通過 @
語法糖實現,是 Python 最強大的特性之一,廣泛應用于日志記錄、權限驗證、性能分析等場景。
作用:
1. 功能增強
- 不侵入原代碼:無需修改函數/類內部邏輯,即可添加新功能(如日志、計時、緩存等)。
- 代碼復用:將通用功能(如權限檢查)抽象為裝飾器,避免重復代碼。
2. 行為修改
- 控制訪問:限制函數調用(如登錄驗證、API 限流)。
- 修改返回值:對函數返回結果進行二次處理(如數據格式化)。
3. 元編程
- 動態注冊:自動注冊函數到框架(如 Flask 路由
@app.route
)。 - AOP(面向切面編程):分離核心邏輯與橫切關注點(如事務管理)。
語法:
裝飾器本質上是一個接收函數/類作為參數,并返回修改后的函數/類的可調用對象。其底層實現基于閉包和高階函數。
def decorator(func): # 1. 接收目標函數def wrapper(*args, **kwargs): # 3. 定義增強邏輯# 前置增強(如權限檢查)result = func(*args, **kwargs) # 4. 調用原函數# 后置增強(如日志記錄)return resultreturn wrapper # 2. 返回包裝后的函數@decorator # 等價于 func = decorator(func)
def func():pass
示例:
① 日志記錄
def log_call(func):def wrapper(*args, **kwargs):print(f"調用 {func.__name__},參數: {args}, {kwargs}")return func(*args, **kwargs)return wrapper@log_call
def add(a, b):return a + badd(2, 3) # 輸出: 調用 add,參數: (2, 3), {}
② 性能計時
import timedef time_it(func):def wrapper(*args, **kwargs):start = time.time()result = func(*args, **kwargs)print(f"{func.__name__} 耗時: {time.time() - start:.2f}s")return resultreturn wrapper@time_it
def slow_function():time.sleep(1)slow_function() # 輸出: slow_function 耗時: 1.00
③ 權限驗證
def login_required(func):def wrapper(user, *args, **kwargs):if not user.is_authenticated:raise PermissionError("請先登錄")return func(user, *args, **kwargs)return wrapper@login_required
def delete_file(user, filename):print(f"{user.name} 刪除了文件 {filename}")# 調用時會自動檢查權限
裝飾器的分類
1. 函數裝飾器
- 最常用形式,作用于函數。
@decorator
def func(): pass
2. 類裝飾器
- 裝飾類,可以修改或替換類行為。
def add_method(cls):cls.new_method = lambda self: print("動態添加的方法")return cls@add_method
class MyClass: passobj = MyClass()
obj.new_method() # 輸出: 動態添加的方法
3. 帶參數的裝飾器
- 通過嵌套函數實現參數傳遞。
def repeat(n):def decorator(func):def wrapper(*args, **kwargs):for _ in range(n):result = func(*args, **kwargs)return resultreturn wrapperreturn decorator@repeat(3)
def say_hello():print("Hello")say_hello() # 輸出 3 次 Hello
4. 內置裝飾器
- Python 自帶的裝飾器,如:
@staticmethod
/@classmethod
:定義靜態方法和類方法。@property
:將方法轉為屬性。@functools.lru_cache
:緩存函數結果。
裝飾器工作原理:
原始函數 → 裝飾器 → 增強后的新函數
常見裝飾器使用場景:
- 日志記錄
- 性能測試(如執行時間)
- 權限校驗
- 緩存
- 事務處理
三、高階函數對比表
以下是 Python 中五大高階函數 map()
、filter()
、reduce()
、sorted()
和裝飾器的詳細對比表格,包含核心特性和使用場景的直觀對比:
1. Python 高階函數對比表
特性 | map() | filter() | reduce() | sorted() | 裝飾器 |
---|---|---|---|---|---|
功能 | 對每個元素應用函數轉換 | 篩選滿足條件的元素 | 累積計算所有元素 | 排序可迭代對象 | 增強或修改函數行為 |
輸入 | (函數, 可迭代對象) | (函數, 可迭代對象) | (函數, 可迭代對象[, 初始值]) | (可迭代對象[, key][, reverse]) | 函數作為輸入 |
輸出類型 | 迭代器(需用 list() 轉換) | 迭代器(需用 list() 轉換) | 單個計算結果 | 新列表 | 返回包裝后的函數 |
是否修改原數據 | ? 生成新數據 | ? 生成新數據 | ? 生成新數據 | ? 生成新列表 | ? 原函數不變 |
典型用途 | 數據轉換(如類型轉換、數學計算) | 數據篩選(如去空值、條件過濾) | 聚合計算(如求和、求積) | 排序(支持自定義規則) | 日志、計時、權限校驗、緩存等 |
依賴模塊 | 內置 | 內置 | from functools import reduce | 內置 | 語法支持(@ ) |
性能特點 | 惰性求值,內存高效 | 惰性求值,內存高效 | 立即計算 | 立即生成新列表 | 運行時增加少量開銷 |
常用搭配 | lambda 、filter 、reduce | lambda 、map | lambda 、map | key= 函數、reverse= | 嵌套裝飾器(如 @log @timer ) |
代碼示例 | map(lambda x: x*2, [1,2,3]) | filter(lambda x: x>0, [-1,0,1]) | reduce(lambda x,y: x+y, [1,2,3]) | sorted([3,1,2], reverse=True) | @decorator def fn(): pass |
2. 關鍵區別圖示
2.1 輸入輸出流程
map: [a,b,c] → [f(a), f(b), f(c)]
filter: [a,b,c] → [a if f(a)=True, c if f(c)=True]
reduce: [a,b,c] → f(f(a,b), c)
sorted: [c,b,a] → [a,b,c]
裝飾器: func → decorated_func
2.2 何時選擇哪個?
需求 | 選擇的高階函數 |
---|---|
批量修改數據 | map() |
按條件過濾數據 | filter() |
計算總和/最大值等聚合 | reduce() |
排序數據 | sorted() |
給函數添加額外功能 | 裝飾器 |
2.3 性能與內存對比
函數 | 惰性求值 | 內存占用 | 適用數據規模 |
---|---|---|---|
map() | ? | 低 | 大規模 |
filter() | ? | 低 | 大規模 |
reduce() | ? | 低 | 中小規模 |
sorted() | ? | 高(生成新列表) | 中小規模 |
3. 經典組合用法示例
from functools import reduce# 1. map + filter: 先過濾再轉換
numbers = [1, 2, 3, 4, 5]
result = list(map(lambda x: x**2, filter(lambda x: x%2==0, numbers)))
# 結果: [4, 16] (僅偶數平方)# 2. sorted + map: 排序轉換后的結果
words = ["apple", "banana", "cherry"]
sorted_by_len = sorted(map(len, words), reverse=True)
# 結果: [6, 6, 5] (按長度降序)# 3. reduce + map: 聚合計算
total = reduce(lambda x,y: x+y, map(float, ["1.5", "2.3"]))
# 結果: 3.8 (字符串轉浮點數后求和)# 4. 裝飾器 + map: 增強函數功能
@log_execution_time
def square(x):return x**2list(map(square, [1, 2, 3])) # 自動記錄執行時間
4. 總結選擇建議
- 需要簡潔性 → 優先用
map
/filter
+lambda
- 需要可讀性 → 簡單邏輯用列表推導式,復雜邏輯用高階函數
- 需要性能 → 大數據用
map
/filter
(惰性求值),避免reduce
處理大規模數據 - 需要擴展功能 → 裝飾器是唯一選擇
四、高階函數的鏈式調用
高階函數可以鏈式調用,形成強大的數據處理管道:
from functools import reducenumbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]# 鏈式調用示例:過濾偶數 → 平方 → 求和
result = reduce(lambda x, y: x + y,map(lambda x: x ** 2,filter(lambda x: x % 2 == 0,numbers))
)print(result) # 輸出: 220 (22 + 42 + 62 + 82 + 102)
數據處理流程:
原始數據 → filter(過濾) → map(轉換) → reduce(聚合) → 最終結果
五、實際應用案例
案例1:學生成績處理
students = [{"name": "Alice", "score": 85},{"name": "Bob", "score": 72},{"name": "Charlie", "score": 90},{"name": "David", "score": 68}
]# 找出及格的學生并按分數降序排列
passed_students = sorted(filter(lambda s: s["score"] >= 60, students),key=lambda x: x["score"],reverse=True
)print(passed_students)
# 輸出: [{'name': 'Charlie', 'score': 90}, {'name': 'Alice', 'score': 85},
# {'name': 'Bob', 'score': 72}, {'name': 'David', 'score': 68}]
案例2:日志記錄裝飾器
def log(func):def wrapper(*args, **kwargs):print(f"開始執行: {func.__name__}")result = func(*args, **kwargs)print(f"執行結束: {func.__name__}")return resultreturn wrapper@log
def add(a, b):return a + bprint(add(3, 5))
# 輸出:
# 開始執行: add
# 執行結束: add
# 8
六、總結
Python的高階函數提供了強大的功能抽象能力,讓我們能夠寫出更簡潔、更易讀的代碼。記住這幾個關鍵點:
- map() - 對每個元素應用函數:“給我一個函數和一個列表,我會把函數應用到每個元素上”
- filter() - 篩選元素:“給我一個條件和一個列表,我會返回滿足條件的元素”
- reduce() - 累積計算:“給我一個計算規則和一個列表,我會把它們累積成一個結果”
- sorted() - 排序:“給我一個列表和排序規則,我會返回排好序的新列表”
- 裝飾器 - 增強函數:“給我一個函數,我會返回一個功能更強的版本”
通過靈活組合這些高階函數,你可以優雅地處理各種數據轉換和計算任務,寫出更"Pythonic"的代碼!