Python itertools 與 functools 高階工具
在 Python 的世界裡,函數與迭代器是一等公民。itertools 與 functools 模組提供了眾多高階工具,讓我們能以「函數式編程」的風格寫出更簡潔、更高效的程式碼。
itertools 模組:迭代器工具
itertools 提供的工具都是「惰性求值」(Lazy Evaluation),這意味著它們只在需要時才計算下一個值,非常省記憶體。
無限迭代與重複
import itertools
# count: 從 N 開始無限計數
# for i in itertools.count(10): print(i)
# cycle: 無限循環一個序列
colors = itertools.cycle(['紅', '綠', '藍'])
print(next(colors)) # 紅
print(next(colors)) # 綠
# repeat: 重複同一個物件
# itertools.repeat('Hello', 3)
組合與排列 (面試常考!)
import itertools
items = ['A', 'B', 'C']
# 排列 (Permutations): 考慮順序
print(list(itertools.permutations(items, 2)))
# [('A', 'B'), ('A', 'C'), ('B', 'A'), ('B', 'C'), ('C', 'A'), ('C', 'B')]
# 組合 (Combinations): 不考慮順序
print(list(itertools.combinations(items, 2)))
# [('A', 'B'), ('A', 'C'), ('B', 'C')]
# 笛卡兒積 (Product): 多個集合的交叉組合
nums = [1, 2]
print(list(itertools.product(items, nums)))
# [('A', 1), ('A', 2), ('B', 1), ('B', 2), ('C', 1), ('C', 2)]
序列處理
itertools.chain(): 將多個列表串聯成一個連續的迭代器。itertools.islice(): 像切片一樣切割迭代器(但不耗盡整個迭代器)。
functools 模組:高階函數工具
functools 專門用於處理函數,特別是「函數裝飾器」與「偏函數」。
lru_cache:自動記憶化 (Caching)
這是一個極度強大的裝飾器,可以快取函數的執行結果。如果用同樣的參數再次呼叫,會直接從記憶體拿結果,特別適合用於遞迴或昂貴運算。
from functools import lru_cache
@lru_cache(maxsize=None)
def fibonacci(n):
if n < 2:
return n
return fibonacci(n-1) + fibonacci(n-2)
print(fibonacci(50)) # 瞬間完成!
partial:偏函數
partial 讓你可以預先固定函數的部分參數,產生一個新的函數。
from functools import partial
def multiply(x, y):
return x * y
# 創建一個專門「乘以 2」的函數
double = partial(multiply, 2)
print(double(10)) # 20
print(double(5)) # 10
wraps:保留原始函數屬性
寫裝飾器時,如果不使用 wraps,被裝飾的函數會「丟失」它的原始名稱 (__name__) 與文檔字串。
from functools import wraps
def my_logger(func):
@wraps(func)
def wrapper(*args, **kwargs):
print(f"呼叫 {func.__name__}...")
return func(*args, **kwargs)
return wrapper
@my_logger
def hello():
"""這是一個問候函數"""
print("Hello!")
print(hello.__name__) # hello (若沒加 wraps 會變成 wrapper)
總結
itertools:當你需要複雜的迴圈邏輯、排列組合、或處理海量數據迭代時,它是首選。functools:當你需要優化函數效能 (lru_cache)、簡化參數調用 (partial)、或撰寫標準化的裝飾器 (wraps) 時,它是必備工具。
掌握這兩個模組,能讓你的 Python 代碼脫胎換骨,從「會寫」進階到「寫得優雅」。