0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Python中 Map/Filter/Reduce的差異

454398 ? 來(lái)源:AI公園 ? 作者:Jonathan Hsu ? 2020-11-17 14:37 ? 次閱讀

作者:Jonathan Hsu
編譯:ronghuaiyang

導(dǎo)讀

想不想去掉瀑布一樣的For循環(huán)?使用函數(shù)式編程來(lái)寫(xiě)代碼。

你有沒(méi)有過(guò)看自己的代碼的時(shí)候,看到瀑布一樣的 for 循環(huán)?你是否發(fā)現(xiàn)自己不得不瞇著眼睛,向顯示器前傾才能看得更清楚?

我知道我有過(guò)。

For 循環(huán)是解決問(wèn)題的瑞士軍刀,但是,當(dāng)需要瀏覽代碼以快速閱讀你所做的事情時(shí),它們可能會(huì)讓人不知所措。

有三種技術(shù) — map、filter 和 reduce — 可以通過(guò)描述如何進(jìn)行迭代來(lái)代替 for 訓(xùn)練。JavaScript 中也有這些技術(shù),但是在 Python 中的實(shí)現(xiàn)略有不同。

我們將簡(jiǎn)要介紹這三種技術(shù)中的每一種,強(qiáng)調(diào)它們?cè)?JavaScript 和 Python 中的語(yǔ)法差異,然后給出如何轉(zhuǎn)換普通 for 循環(huán)的示例。

什么是 Map, Filter, 以及 Reduce?

回顧之前寫(xiě)的代碼,我發(fā)現(xiàn)在 95%的情況下,當(dāng)循環(huán)遍歷字符串或數(shù)組時(shí),我是這樣做的:將序列map到每個(gè)值,filter滿足特定條件的值,或者將數(shù)據(jù)集reduce到單個(gè)聚合值。

有了這樣的認(rèn)識(shí),這三種方法就是識(shí)別 —— 然后實(shí)現(xiàn),你遍歷 iterable 的原因通常屬于這三種功能中的一種:

Map:對(duì)每個(gè)一項(xiàng)應(yīng)用相同步驟的操作,然后存儲(chǔ)結(jié)果。

Filter:應(yīng)用驗(yàn)證標(biāo)準(zhǔn),存儲(chǔ)評(píng)估為真的項(xiàng)。

Reduce:返回一個(gè)在元素之間傳遞的值。

Python 中 Map/Filter/Reduce 的不同點(diǎn)是什么?

在 Python 中,這三種技術(shù)以函數(shù)的形式存在,而不是以數(shù)組或字符串類的方法。這意味著不要寫(xiě)成my_array.map(function),而要寫(xiě)成map(function, my_list)。

此外,每種技術(shù)都需要傳遞一個(gè)函數(shù),該函數(shù)將為每個(gè)一項(xiàng)執(zhí)行。通常,函數(shù)被寫(xiě)成匿名函數(shù)(在 JavaScript 中稱為胖箭頭函數(shù))。但是,在 Python 中經(jīng)??吹绞褂?lambda 表達(dá)式。

lambda 表達(dá)式和箭頭函數(shù)之間的語(yǔ)法實(shí)際上非常相似。將' => '替換為':',并確保使用關(guān)鍵字' lambda ',其余內(nèi)容幾乎相同。

// JavaScript Arrow Function
const square = number => number * number;
// Python Lambda Expression
square = lambda number: number * number

箭頭函數(shù)和 lambda 表達(dá)式之間的一個(gè)關(guān)鍵區(qū)別是,箭頭函數(shù)可以擴(kuò)展成包含多條語(yǔ)句的完整函數(shù),而 lambda 表達(dá)式則被限制為返回的單個(gè)表達(dá)式。因此,在使用map()、filter()或reduce() 的時(shí)候,如果你需要對(duì)每個(gè)項(xiàng)執(zhí)行多個(gè)操作,那么首先定義函數(shù),然后將其包含進(jìn)來(lái)。

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

替換 For 循環(huán)

好吧,說(shuō)正事。下面是三個(gè)常見(jiàn)的 for 循環(huán)示例,它們將被 map、filter 和 reduce 替換。我們的編程提示:計(jì)算列表中奇數(shù)的平方和。

首先,使用 basic for 循環(huán)的例子。注意:這純粹是為了演示,甚至可以在沒(méi)有 map/filter/reduce 的情況下進(jìn)行改進(jìn)。

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

讓我們把每一步轉(zhuǎn)換為一個(gè)函數(shù):

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)

有幾個(gè)重要的語(yǔ)法點(diǎn)需要突出顯示。

map()和filter()是本地可用的。但是,reduce()必須從 Python 3+的functools庫(kù)中導(dǎo)入。

lmbda 表達(dá)式是所有三個(gè)函數(shù)中的第一個(gè)參數(shù),而 iterable 是第二個(gè)參數(shù)

reduce()的 lambda 表達(dá)式需要兩個(gè)參數(shù):累加器(傳遞給每個(gè)元素的值)和單個(gè)元素本身。

編輯:hfy

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 顯示器
    +關(guān)注

    關(guān)注

    21

    文章

    4862

    瀏覽量

    139352
  • python
    +關(guān)注

    關(guān)注

    53

    文章

    4753

    瀏覽量

    84075
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    python:利用mapreduce編寫(xiě)一個(gè)str2float函數(shù),把字符串'.1'轉(zhuǎn)換成浮點(diǎn)數(shù)0.1:

    #!/usr/bin/env python3# -*- coding: utf-8 -*-from functools import reduceCHAR_TO_FLOAT = { '0': 0
    發(fā)表于 07-16 01:27

    python初學(xué)--用map規(guī)范英文名字

    進(jìn)入第3天學(xué)習(xí),接觸到第一個(gè)練習(xí),利用 map() 函數(shù),把用戶輸入的不規(guī)范的英文名字,變?yōu)槭鬃帜复髮?xiě),其他小寫(xiě)的規(guī)范名字。輸入: ['adam', 'LISA', 'barT'] ,輸出
    發(fā)表于 12-25 14:47

    python高階函數(shù)

    注意的是,以上示例是在 Python2.x 環(huán)境下演示的。而在 Python3.x ,卻有所不同,你可以自己嘗試一下。這里總結(jié)一下:第一點(diǎn),map
    發(fā)表于 03-02 16:47

    紋理映射技術(shù)Mip_Map的研究_曾云

    紋理映射技術(shù)Mip_Map的研究_曾云
    發(fā)表于 03-15 11:08 ?0次下載

    Python的三種函數(shù)應(yīng)用及代碼

    1.filter的用法 函數(shù)filter(function,list)提供一種優(yōu)雅的方式過(guò)濾出列表函數(shù)值返回為T(mén)rue的函數(shù),函數(shù)filter(f,l)需要一個(gè)函數(shù)f作為第一個(gè)參數(shù),
    發(fā)表于 11-15 13:07 ?1324次閱讀
    <b class='flag-5'>Python</b>的三種函數(shù)應(yīng)用及代碼

    Reduce階段values的每個(gè)值都共享一個(gè)對(duì)象

    Hadoop備忘:Reduce階段IterableVALUEIN values的每個(gè)都共享一個(gè)對(duì)象。在Reduce階段,具有相同key的的所有的value都會(huì)被組織到一起,形成一種key:values的形式。
    發(fā)表于 11-28 11:00 ?1311次閱讀

    mapreduce MAP進(jìn)程的數(shù)量怎么控制?

    1.如果想增加map個(gè)數(shù),則設(shè)置mapred.map.tasks 為一個(gè)較大的值2.如果想減小map個(gè)數(shù),則設(shè)置mapred.min.split.size 為一個(gè)較大的值3.如果輸入中有很多小文件,依然想減少
    發(fā)表于 01-02 14:04 ?1842次閱讀
    mapreduce <b class='flag-5'>中</b><b class='flag-5'>MAP</b>進(jìn)程的數(shù)量怎么控制?

    Mapreduce和Hivemap reduce個(gè)數(shù)設(shè)定

    Mapreducemapper個(gè)數(shù)的確定: 在map階段讀取數(shù)據(jù)前,F(xiàn)ileInputFormat會(huì)將輸入文件分割成split。split的個(gè)數(shù)決定了map的個(gè)數(shù)。 影響map個(gè)數(shù),
    發(fā)表于 01-02 14:21 ?6024次閱讀

    mapreduce工作原理圖文詳解_Map、Reduce任務(wù)Shuffle和排序

    本文主要分析以下兩點(diǎn)內(nèi)容:1.MapReduce作業(yè)運(yùn)行流程原理2.MapReduce任務(wù)Shuffle和排序的過(guò)程。分析如下文
    發(fā)表于 01-02 14:39 ?8431次閱讀
    mapreduce工作原理圖文詳解_<b class='flag-5'>Map</b>、<b class='flag-5'>Reduce</b>任務(wù)<b class='flag-5'>中</b>Shuffle和排序

    MDK- ARMmap文件全解析

    MDK-ARMmap文件全解析
    的頭像 發(fā)表于 03-14 14:00 ?5807次閱讀
    MDK- ARM<b class='flag-5'>中</b><b class='flag-5'>map</b>文件全解析

    python高階函數(shù)詳解

    python高階函數(shù) 1. map 函數(shù) map 函數(shù),它接收兩個(gè)參數(shù),第一個(gè)參數(shù)是一個(gè)函數(shù)對(duì)象(當(dāng)然也可以是一個(gè)lambda表達(dá)式),第二個(gè)參數(shù)是一個(gè)序列。 它可以實(shí)現(xiàn)怎樣的功能呢,我舉個(gè)例子你
    的頭像 發(fā)表于 03-02 16:47 ?1216次閱讀
    <b class='flag-5'>python</b>高階函數(shù)詳解

    Python 和 MicroPython 之間的差異

    Python 和 MicroPython 之間的差異
    的頭像 發(fā)表于 12-28 09:51 ?3366次閱讀

    NIVDIA的reduce優(yōu)化筆記

    通俗的來(lái)說(shuō),Reduce就是要對(duì)一個(gè)數(shù)組求 sum,min,max,avg 等等。Reduce又被叫作規(guī)約,意思就是遞歸約減,最后獲得的輸出相比于輸入一般維度上會(huì)遞減。
    的頭像 發(fā)表于 01-12 15:05 ?629次閱讀

    Ruby 與 Python之間的差異

    Ruby 與 Python 之間的差異在很大程度上可通過(guò) for 循環(huán)看出本質(zhì)。 Python 擁有 for 語(yǔ)句。對(duì)象告訴 for 如何進(jìn)行協(xié)作,而 for 的循環(huán)體會(huì)處理對(duì)象返回的內(nèi)容
    的頭像 發(fā)表于 10-30 11:50 ?524次閱讀

    Python2與Python3的差異

    Python2與Python3是兩個(gè)不同的版本,它們?cè)谡Z(yǔ)法、功能和性能等方面存在一些差異。下面是對(duì)Python2和Python3的詳盡、詳實(shí)
    的頭像 發(fā)表于 11-23 16:48 ?706次閱讀