作者:Jonathan Hsu
編譯:ronghuaiyang
導讀
想不想去掉瀑布一樣的For循環?使用函數式編程來寫代碼。
你有沒有過看自己的代碼的時候,看到瀑布一樣的 for 循環?你是否發現自己不得不瞇著眼睛,向顯示器前傾才能看得更清楚?
我知道我有過。
For 循環是解決問題的瑞士軍刀,但是,當需要瀏覽代碼以快速閱讀你所做的事情時,它們可能會讓人不知所措。
有三種技術 — map、filter 和 reduce — 可以通過描述如何進行迭代來代替 for 訓練。JavaScript 中也有這些技術,但是在 Python 中的實現略有不同。
我們將簡要介紹這三種技術中的每一種,強調它們在 JavaScript 和 Python 中的語法差異,然后給出如何轉換普通 for 循環的示例。
什么是 Map, Filter, 以及 Reduce?
回顧之前寫的代碼,我發現在 95%的情況下,當循環遍歷字符串或數組時,我是這樣做的:將序列map到每個值,filter滿足特定條件的值,或者將數據集reduce到單個聚合值。
有了這樣的認識,這三種方法就是識別 —— 然后實現,你遍歷 iterable 的原因通常屬于這三種功能中的一種:
Map:對每個一項應用相同步驟的操作,然后存儲結果。
Filter:應用驗證標準,存儲評估為真的項。
Reduce:返回一個在元素之間傳遞的值。
Python 中 Map/Filter/Reduce 的不同點是什么?
在 Python 中,這三種技術以函數的形式存在,而不是以數組或字符串類的方法。這意味著不要寫成my_array.map(function),而要寫成map(function, my_list)。
此外,每種技術都需要傳遞一個函數,該函數將為每個一項執行。通常,函數被寫成匿名函數(在 JavaScript 中稱為胖箭頭函數)。但是,在 Python 中經常看到使用 lambda 表達式。
lambda 表達式和箭頭函數之間的語法實際上非常相似。將' => '替換為':',并確保使用關鍵字' lambda ',其余內容幾乎相同。
// JavaScript Arrow Function const square = number => number * number; // Python Lambda Expression square = lambda number: number * number
箭頭函數和 lambda 表達式之間的一個關鍵區別是,箭頭函數可以擴展成包含多條語句的完整函數,而 lambda 表達式則被限制為返回的單個表達式。因此,在使用map()、filter()或reduce() 的時候,如果你需要對每個項執行多個操作,那么首先定義函數,然后將其包含進來。
def inefficientSquare(number): result = number * number return result map(inefficientSquare, my_list)
替換 For 循環
好吧,說正事。下面是三個常見的 for 循環示例,它們將被 map、filter 和 reduce 替換。我們的編程提示:計算列表中奇數的平方和。
首先,使用 basic for 循環的例子。注意:這純粹是為了演示,甚至可以在沒有 map/filter/reduce 的情況下進行改進。
numbers = [1,2,3,4,5,6] odd_numbers = [] squared_odd_numbers = [] total = 0 # filter for odd numbers for number in numbers: if number % 2 == 1: odd_numbers.append(number) # square all odd numbers for number in odd_numbers: squared_odd_numbers.append(number * number) # calculate total for number in squared_odd_numbers: total += number # calculate average
讓我們把每一步轉換為一個函數:
from functools import reduce numbers = [1,2,3,4,5,6] odd_numbers = filter(lambda n: n % 2 == 1, numbers) squared_odd_numbers = map(lambda n: n * n, odd_numbers) total = reduce(lambda acc, n: acc + n, squared_odd_numbers)
有幾個重要的語法點需要突出顯示。
map()和filter()是本地可用的。但是,reduce()必須從 Python 3+的functools庫中導入。
lmbda 表達式是所有三個函數中的第一個參數,而 iterable 是第二個參數
reduce()的 lambda 表達式需要兩個參數:累加器(傳遞給每個元素的值)和單個元素本身。
編輯:hfy
-
顯示器
+關注
關注
21文章
5065瀏覽量
141420 -
python
+關注
關注
56文章
4825瀏覽量
86266
發布評論請先 登錄
python:利用map和reduce編寫一個str2float函數,把字符串'.1'轉換成浮點數0.1:
python初學--用map規范英文名字
python高階函數
Python的三種函數應用及代碼

Reduce階段values中的每個值都共享一個對象
mapreduce 中MAP進程的數量怎么控制?

Mapreduce和Hive中map reduce個數設定
mapreduce工作原理圖文詳解_Map、Reduce任務中Shuffle和排序

python高階函數詳解

評論