Python編程技巧:如何用Map, Filter, Reduce代替For循環?

2020-12-17 雷鋒網

你是否有過這樣的經歷,你查看自己寫的代碼並看到滿眼的 for 循環?你發現你必須斜著你的眼睛,並將腦袋前傾到你的顯示器,以看得更清楚。

反正我有過這樣的經歷。

for 循環就像是一把瑞士軍刀,它可以解決很多問題,但是,當你需要掃視代碼,快速搞清楚代碼所做的事情時,它們可能會讓人不知所措。

map、filter 和 reduce 這三種技術可以提供描述迭代原因的函數替代方案,以便避免過多的 for 循環。我之前在 JavaScript 中寫過這些技術的入門文章,但是它們在 Python 中的實現略有不同。

我們將簡要介紹這三種技術,主要介紹它們在 JavaScript 和 Python 中的語法差異,然後給出如何轉換 for 循環的示例。

什麼是 Map、Filter 和 Reduce?

回顧我以前編寫的代碼,我意識到 95% 的時間都花在遍歷字符串或數組上。在這種情況下,我會執行以下操作之一:將一系列語句映射到每個值,篩選滿足特定條件的值,或將數據集減少為單個聚合值。

有了這種洞察力,你就可以識別和實現這三種方法,即循環遍歷通常屬於這三種功能類別之一:

Map:對每個項應用相同的步驟集,存儲結果Filter:應用驗證條件,存儲計算結果為 True 的項Reduce:返回一個從元素傳遞到元素的值為什麼 Python Map/Filter/Reduce 會不一樣?

在 Python 中,這三種技術作為函數存在,而不是數組或字符串類的方法。這意味著,你將編寫 map(function, my_list),而不是編寫 my_array.map(function)。

此外,每個技術都需要傳遞一個函數,該函數將執行每個項目。通常,該函數是作為匿名函數(在 JavaScript 中稱為 arrow 頭函數)編寫的。但是,在 Python 中,你經常看到被使用的是 lambda 表達式。

lambda 表達式和 arrow 函數之間的語法實際上非常相似。將 => 替換為 : 並確保使用關鍵字 lambda,其餘的幾乎相同。

// JavaScript Arrow Functionconst square = number => number * number;// Python Lambda Expressionsquare = lambda number: number * number

arrow 函數和 lambda 表達式之間的一個關鍵區別是,arrow 函數能夠通過多個語句擴展成完整的函數,而 lambda 表達式僅限於返回的單個表達式。因此,在使用 map()、filter()或 reduce()時,如果需要對每個項執行多個操作,請先定義函數,然後再包含它。

def inefficientSquare(number):result = number * number return resultmap(inefficientSquare, my_list)

替換 for 循環

好了,下面來點好東西。下面是三個常見的 for 循環示例,它們將被 map、filter 和 reduce 替換。我們的編程目標:計算列表中奇數平方和。

首先,使用 基本的 for 循環示例。注意:下面的代碼純粹是為了演示,即使沒有 map/filter/reduce 也有改進空間。

numbers = [1,2,3,4,5,6]odd_numbers = []squared_odd_numbers = []total = 0# filter for odd numbersfor number in numbers:if number % 2 == 1: odd_numbers.append(number)# square all odd numbersfor number in odd_numbers: squared_odd_numbers.append(number * number)# calculate totalfor number in squared_odd_numbers: total += number# calculate average

讓我們將每個步驟轉換為這三個函數的其中之一:

from functools import reducenumbers = [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 以上版本中的函數庫導入lambda 表達式是所有三個函數中的第一個參數,iterable 是第二個參數reduce()的 lambda 表達式需要兩個參數:累加器(傳遞給每個元素的值)和單個元素本身記住,for 循環在代碼中確實是很重要的,但是擴展工具包從來都不是壞事。

via:https://medium.com/better-programming/how-to-replace-your-python-for-loops-with-map-filter-and-reduce-c1b5fa96f43a

雷鋒網雷鋒網雷鋒網

相關焦點

  • 如何用Map、Filter和Reduce替換Python For循環?
    (難以切齒)For循環是解決問題的瑞士軍刀,非常好用,但是當瀏覽代碼想看看自己做了什麼的時候,它們會把你淹沒。此時,Map, filter和 reduce三種技術可以幫到你。它們可以通過提供描述迭代原因的函數替代選擇,來矯正For循環的狂熱。
  • python高階函數:map、filter、reduce的替代品
    在函數式編程中,大家最熟悉的高階函數主要有map函數、filter函數、reduce函數和apply函數。python3中移除了apply。如果想使用不定量的參數調用函數,可以使用fn(*args,**keywords),不用再使用apply(fn,args,keywords)。
  • Python 進階之術 Map Filter Reduce
    >def multiply(x): return (x*x)def add(x): return (x+x)funcs = [multiply, add]for i in range(5): value = map(lambda x: x(i), funcs)print(list(value))# 上⾯print時,加了list轉換,是為了python2/3
  • 詳解Python函數式編程之map、reduce、filter
    map()、reduce()、filter()是Python中很常用的幾個函數,也是Python支持函數式編程的重要體現。
  • python3 map、reduce、filter 的區別
    在 Python 中有一種編程模式叫做函數式編程,使用的就是 map、reduce、filter 這樣的高階函數(累計函數):對於序列內所有元素進行累計操作,這個函數必須接收兩個參數,reduce 把結果繼續和序列的下一個元素做累積計算
  • 5分鐘掌握Python | Map、Reduce和Filter如何運用?
    今天給大家介紹的是Python當中三個非常神奇的方法:map、reduce和filter。Map除了地圖之外,另一個英文本意是映射。在C++和Java一些語言當中,將map進一步引申成了存儲key和value映射結構的容器。
  • Python專題——五分鐘帶你了解map、reduce和filter
    今天是Python專題第6篇文章,給大家介紹的是Python當中三個非常神奇的方法:map、reduce和filter。不知道大家看到map和reduce的時候有沒有什麼感覺,如果看過之前我們大數據系列介紹MapReduce文章的同學,想必有些印象。這個MapReduce不是一個分布式的計算方法麼,怎麼又變成Python中的方法了?
  • 圖解 Map、Reduce 和 Filter 數組方法
    、reduce 和 filter 是三個非常實用的 JavaScript 數組方法,賦予了開發者四兩撥千斤的能力。我們直接進入正題,看看如何使用(並記住)這些超級好用的方法!Array.map()Array.map() 根據傳遞的轉換函數,更新給定數組中的每個值,並返回一個相同長度的新數組。它接受一個回調函數作為參數,用以執行轉換過程。let newArray = oldArray.map((value, index, array) => { ...
  • 一文看懂Python列表表達式及高階函數如lamda, zip, enumerate, map和filter方法.
    深入了解和熟練使用python的列表表達式和內置的一些高階函數如lamda, zip, enumerate, map, filter, reduce
  • 【第1589期】圖解 Map、Reduce 和 Filter 數組方法
    正文從這開始~~map、reduce 和 filter 是三個非常實用的 JavaScript 數組方法,賦予了開發者四兩撥千斤的能力。我們直接進入正題,看看如何使用(並記住)這些超級好用的方法!Array.map()Array.map() 根據傳遞的轉換函數,更新給定數組中的每個值,並返回一個相同長度的新數組。
  • Python基礎應用:map與reduce
    map()和 reduce() 函數的設計靈感就來源於函數式編程的思想。簡單講,函數式編程的主要思想是儘量將運算過程編寫成一系列的嵌套函數。 map() 和 reduce() 都是Python內置的高階函數。所謂高階函數,即以函數作為輸入參數或輸出結果的函數,map() 和 reduce()的共同特徵是以函數作為傳入參數。
  • 從頭使用.map() .filter() 和.reduce(),你會有意想不到的收穫!
    在「碼農圈」,學習如何使用.map()、.filter()和.reduce()函數,我們讀到、看到和聽到的一切都很複雜,無法理解這些概念,因為它們是獨立的學習單元。聽說這些是意味著上升至啟蒙狀態的入門知識。
  • 案例詳解:filter 過濾、map 映射、reduce累積
    filter(function, iterable)參數:function -- 判斷函數iterable -- 可迭代對象#  filter 過濾num=[2,3,7,9,17,12,5]filter(lambda y:y>10,num) #輸出:[17,12]
  • 科學使用python中的Map函數和Filter函數
    歡迎關注 「小白玩轉Python」,發現更多 「有趣」map函數假設我們想要用現有列表創建一個新的列表,也就是說要在現有列表的基礎上,對列表的每個元素進行某種操作,然後將結果輸出來創建一個新的列表。例如,有一個數字列表,而我們想創建一個包含其平方的新列表。
  • 實例中學習python的walk/map/filter/lambda
    我們本次就從此實例出發,去學習python語言中的walk/map/filter/lambda函數的使用。我們測試環境的當前目錄下除了兩個代碼文件:jsj_xx_1.py和jsj_xx_2.py,其餘都是測試相關的目錄和文件,具體如下:實例的需求是找到當前目錄下的後綴名為「.name1」和「.name2」的文件。
  • reduce()函數和filter()函數閃亮登場
    導讀  Python中有很多非常好用的函數,這些函數不僅簡單實用,而且可以簡化代碼,提高我們的工作效率。在推文《優雅的map()》中,我們向大家介紹了map()函數的使用方法。今天給大家帶來了另外兩個相當實用的Python函數——reduce()函數和filter()函數。大家想對這兩個函數有進一步了解的話,就請繼續看下去吧!
  • Python入門基礎之map()、reduce()函數使用
    本文環境都是基於python3.X的,畢竟要學會擁抱未來,擁抱新的知識。Python3 現在已經發展的差不多了。1、 map()函數map()是 python 內置的高階函數,它接收一個函數 f 和一個 list,並通過把函數 f 依次作用在 list 的每個元素上,得到一個新的object並返回。
  • 「 JS-三個高階函數filter-map-reduce 」
    前言: JS-三個高階函數filter-map-reduce,需要掌握,很好用,真香警告。filterfilter 有過濾的意思filter(參數) 方法創建一個新的數組,新數組中的元素是通過檢查指定數組中符合條件的所有元素。
  • 一文讀懂python的map、reduce函數
    這對兄弟是出現頻率極高且相當實用的python函數,初學者會較難理解,看完本文你就能搞定它們嘍!如何使用map函數?reduce函數怎麼用?reduce(function, iterable[, initializer])function:代表函數iterable:序列initializer:初始值(可選)與map不同,reduce不可以直接使用,需要用from functools import reduce
  • 在JavaScript函數式編程裡使用Map和Reduce方法
    你也許知道剛才我描述的在一個數組上使用for循環如何做。這取決於你在現實中準備如何去使用這些代碼。這種實現方式沒有任何的技術錯誤。它在任何標準的JavaScript引擎裡都可以用,並且它能很好的完成工作。一旦你知道怎麼使用map()方法了,通過這種方法來實現就顯得有些笨拙了。