重構過濾器並對映到列表推導
filter
或 map
函式通常應該由列表推導替換。Guido Van Rossum 在 2005 年的一封公開信中描述了這一點 :
filter(P, S)
幾乎總是像[x for x in S if
P(x)]
一樣更加清晰,這有一個巨大的優勢,即最常見的用法涉及比較的謂詞,例如x==42
,並且定義一個 lambda,這對讀者來說需要更多的努力(加上 lambda 比列表理解)。對於map(F, S)
來說更是如此。當然,在許多情況下,你可以使用生成器表示式。
以下程式碼行被認為是“ 非 pythonic ”,並且會在許多 python linters 中引發錯誤。
filter(lambda x: x % 2 == 0, range(10)) # even numbers < 10
map(lambda x: 2*x, range(10)) # multiply each number by two
reduce(lambda x,y: x+y, range(10)) # sum of all elements in list
根據我們從前面的引文中學到的東西,我們可以將這些 filter
和 map
表示式分解為它們的等效列表推導 ; 還從每個函式中刪除 lambda 函式 - 使程式碼在此過程中更具可讀性。
# Filter:
# P(x) = x % 2 == 0
# S = range(10)
[x for x in range(10) if x % 2 == 0]
# Map
# F(x) = 2*x
# S = range(10)
[2*x for x in range(10)]
在處理連結函式時,可讀性變得更加明顯。由於可讀性,一個對映或過濾函式的結果應該作為結果傳遞給下一個; 在簡單的情況下,這些可以用單個列表理解來代替。此外,我們可以很容易地從列表中瞭解我們的過程的結果是什麼,在推斷鏈式 Map 和 Filter 過程時有更多的認知負荷。
# Map & Filter
filtered = filter(lambda x: x % 2 == 0, range(10))
results = map(lambda x: 2*x, filtered)
# List comprehension
results = [2*x for x in range(10) if x % 2 == 0]
重構 - 快速參考
-
地圖
map(F, S) == [F(x) for x in S]
-
過濾
filter(P, S) == [x for x in S if P(x)]
其中 F
和 P
是分別轉換輸入值並返回 bool
的函式