国产睡熟迷奷白丝护士系列精品,中文色字幕网站,免费h网站在线观看的,亚洲开心激情在线

      <sup id="hb9fh"></sup>
          1. 千鋒教育-做有情懷、有良心、有品質(zhì)的職業(yè)教育機(jī)構(gòu)

            手機(jī)站
            千鋒教育

            千鋒學(xué)習(xí)站 | 隨時(shí)隨地免費(fèi)學(xué)

            千鋒教育

            掃一掃進(jìn)入千鋒手機(jī)站

            領(lǐng)取全套視頻
            千鋒教育

            關(guān)注千鋒學(xué)習(xí)站小程序
            隨時(shí)隨地免費(fèi)學(xué)習(xí)課程

            當(dāng)前位置:首頁(yè)  >  技術(shù)干貨  > Python之map、reduce和filter

            Python之map、reduce和filter

            來(lái)源:千鋒教育
            發(fā)布人:xqq
            時(shí)間: 2023-11-07 13:01:34 1699333294

            今天給大家介紹的是Python當(dāng)中三個(gè)非常神奇的方法:map、reduce和filter。

            不知道大家看到map和reduce的時(shí)候有沒(méi)有什么感覺(jué),如果看過(guò)之前我們大數(shù)據(jù)系列介紹MapReduce文章的同學(xué),想必有些印象。這個(gè)MapReduce不是一個(gè)分布式的計(jì)算方法么,怎么又變成Python中的方法了?其實(shí)原因很簡(jiǎn)單,因?yàn)镻ython是一門很年輕的語(yǔ)言,它在發(fā)展的過(guò)程當(dāng)中吸收了很多其他領(lǐng)域的精華,MapReduce就是其中之一。

            對(duì)之前文章感興趣的同學(xué)可以點(diǎn)擊下方的鏈接,回顧一下之前MapReduce的內(nèi)容。

            大數(shù)據(jù)基石——Hadoop與MapReduce

            mapmap除了地圖之外,另一個(gè)英文本意是映射。在C++和Java一些語(yǔ)言當(dāng)中,將map進(jìn)一步引申成了存儲(chǔ)key和value映射結(jié)構(gòu)的容器。Python對(duì)這點(diǎn)做了區(qū)分,KV結(jié)構(gòu)的容器命名成了dict,即字典,而map則回到了它的本意,也就是映射。

            我們都知道,在數(shù)學(xué)領(lǐng)域,映射也是函數(shù)的定義。一個(gè)自變量通過(guò)某種映射,對(duì)應(yīng)到一個(gè)因變量。同樣,在Python當(dāng)中,map操作本質(zhì)也是函數(shù),不過(guò)它作用的范圍不再是單個(gè)變量,而是一個(gè)序列。換句話說(shuō),通過(guò)map我們可以省去循環(huán)操作,可以自動(dòng)將一個(gè)容器當(dāng)中的元素套用一個(gè)函數(shù)。

            舉個(gè)簡(jiǎn)單的例子,比如我們有一個(gè)坐標(biāo),我們希望知道它距離原點(diǎn)的距離。這個(gè)問(wèn)題很簡(jiǎn)單,我們寫一個(gè)計(jì)算距離的函數(shù)就可以解決:

            defdis(point):

            returnmath.sqrt(point[0]**2+point[1]**2)

            那如果我有多個(gè)點(diǎn)需要計(jì)算距離,在map出現(xiàn)之前,我們只能用循環(huán)來(lái)解決問(wèn)題:

            points=[[0,1],[2,4],[3,2]]

            forpointinpoints:

            print(dis(point))

            但是有了map之后,我們可以省去循環(huán)的操作,整個(gè)代碼簡(jiǎn)化成了一行:

            map(dis,points)

            但是要注意,我們調(diào)用完map之后得到的結(jié)果不是一個(gè)list而是一個(gè)迭代器。我們直接將map返回的內(nèi)容print出來(lái),可以得到這樣一個(gè)結(jié)果:

            >>>print(map(dis,points))

            這是一個(gè)類的標(biāo)準(zhǔn)輸出,其實(shí)它返回的不是最后的結(jié)果,而是一個(gè)迭代器。我們?cè)谥暗奈恼庐?dāng)中已經(jīng)介紹過(guò)了迭代器和生成器的相關(guān)概念,這里不多做贅述了,遺忘的同學(xué)可以點(diǎn)擊下方鏈接回顧一下之前的內(nèi)容:

            Python——五分鐘帶你弄懂迭代器與生成器

            我們想要獲得完整的內(nèi)容也很容易,我們只需要將它轉(zhuǎn)化成list類型即可:

            >>>print(list(map(dis,points)))

            [1.0,4.47213595499958,3.605551275463989]

            以上過(guò)程還可以進(jìn)一步簡(jiǎn)化,還記得我們之前介紹過(guò)的匿名函數(shù)嗎?由于dis函數(shù)在我們的程序當(dāng)中只會(huì)在map中用到,我們完全沒(méi)有必要單獨(dú)創(chuàng)建一個(gè)函數(shù),我們可以直接傳入一個(gè)匿名函數(shù)搞定運(yùn)算:

            map(lambdax:math.sqrt(x[0]**2+x[1]**2),points)

            簡(jiǎn)單總結(jié)一下,map操作其實(shí)執(zhí)行的是一個(gè)映射。它可以自動(dòng)地將一個(gè)序列當(dāng)中的內(nèi)容通過(guò)制定的函數(shù)映射成另一個(gè)序列,從而避免顯式地使用循環(huán)來(lái)調(diào)用,在很多場(chǎng)景下可以大大地簡(jiǎn)化代碼的編寫,可以很方便地將一個(gè)序列整體轉(zhuǎn)變成另一個(gè)結(jié)果。

            reduce相比于map,reduce的操作稍稍難理解一點(diǎn)點(diǎn)。它也是規(guī)定一個(gè)映射,不過(guò)不是將一個(gè)元素映射成一個(gè)結(jié)果。而是將兩個(gè)元素歸并成一個(gè)結(jié)果。并且它并不是調(diào)用一次,而是依次調(diào)用,直到最后只剩下一個(gè)結(jié)果為止。

            比如說(shuō)我們有一個(gè)數(shù)組[a,b,c,d]和一個(gè)函數(shù)f,我們計(jì)算reduce(f,[a,b,c,d])其實(shí)就等價(jià)于f(f(f(a,b),c),d)。和map不同的是,reduce最后得到一個(gè)結(jié)果,而不是一個(gè)迭代器或者是list。

            我們光說(shuō)有些抽象,不妨來(lái)看一個(gè)例子,就看最簡(jiǎn)單的一個(gè)例子:reduce函數(shù)接收兩個(gè)數(shù),返回兩個(gè)數(shù)的和。那么顯然,我們依次調(diào)用reduce,得到的就是原數(shù)組的和。

            fromfunctoolsimportreduce

            deff(a,b):

            returna+b

            print(reduce(f,[1,2,3,4]))

            最終得到的結(jié)果當(dāng)然是10,同樣,我們也可以將reduce中的方法定義成匿名函數(shù),一樣不影響最終的結(jié)果。

            print(reduce(lambdax,y:x+y,[1,2,3,4]))

            MapReduce既然我們map和reduce都有了,顯然我們可以將它們串聯(lián)起來(lái)使用,也就是分布式系統(tǒng)當(dāng)中MapReduce的做法。雖然如果不手動(dòng)使用線程池的話,Python并不會(huì)起多個(gè)線程來(lái)加速運(yùn)算,但是至少可以簡(jiǎn)化我們實(shí)現(xiàn)的代碼。我們還是舉經(jīng)典的wordCount的例子,也就是文本計(jì)算詞頻。

            套用map和reduce的功能,整個(gè)流程非常清晰,我們只需要在map階段對(duì)文本進(jìn)行分詞,在reduce階段對(duì)分詞之后的結(jié)果進(jìn)行匯總即可。

            聽著好像非常容易,但是你實(shí)際去上手是寫不出來(lái)的。原因也很簡(jiǎn)單,因?yàn)閔adoop當(dāng)中的Map和Reduce中間還有一層shuffle的操作,會(huì)自動(dòng)地將key值相同的結(jié)果放到同一個(gè)reducer當(dāng)中。在這個(gè)問(wèn)題當(dāng)中,key自然就是我們的word,由于相同的word被放到同一個(gè)reducer當(dāng)中,我們只需要累加就行了。但是如果我們自己編寫mapreduce的話,由于缺少了中間數(shù)據(jù)重排的步驟,所以導(dǎo)致不能實(shí)現(xiàn)。

            要解決也簡(jiǎn)單,我們可以人為增加一個(gè)map階段代替hadoop當(dāng)中的重排。相當(dāng)于做了一個(gè)MapMapReduce,我們來(lái)看代碼:

            fromcollectionsimportCounter,defaultdict

            texts=['applebearpeachgrape','grapeorangepear']

            #第一次map,將字符串轉(zhuǎn)成數(shù)組,每個(gè)單詞對(duì)應(yīng)1

            defmp1(text):

            ret=[]

            words=text.split('')

            forwordinwords:

            ret.append((word,1))

            returnret

            #第二次map,將數(shù)組轉(zhuǎn)成dict

            defmp2(arr):

            d=defaultdict(int)

            fork,vinarr:

            d[k]+=v

            returnd

            #reduce,合并dict

            defrd(x,y):

            x.update(y)

            returnx

            print(reduce(rd,map(mp2,map(mp1,texts))))

            那如果我們不用多次MapReduce呢?也不是沒(méi)有辦法,需要取點(diǎn)巧,方法也簡(jiǎn)單只要使用之前我們講解過(guò)的Counter類,就可以完美解決這個(gè)問(wèn)題。我們來(lái)看代碼:

            fromcollectionsimportCounter

            texts=['applebearpeachgrape','grapeorangepear']

            defmp(text):

            words=text.split('')

            returnCounter(words)

            print(reduce(lambdax,y:x+y,map(mp,texts)))

            由于我們使用了Counter,所以我們?cè)趍ap階段返回的結(jié)果就已經(jīng)是詞頻的dict了,而在reduce階段我們只需要將它們?nèi)坷奂悠饋?lái)就OK了。

            最后,我們來(lái)看下filter。

            filterfilter的英文是過(guò)濾,所以它的使用就很明顯了。它的用法和map有些類似,我們編寫一個(gè)函數(shù)來(lái)判斷元素是否合法。通過(guò)調(diào)用filter,會(huì)自動(dòng)將這個(gè)函數(shù)應(yīng)用到容器當(dāng)中所有的元素上,最后只會(huì)保留運(yùn)行結(jié)果是True的元素,而過(guò)濾掉那些是False的元素。

            舉個(gè)例子,假設(shè)我們想要保留list當(dāng)中的奇數(shù)而過(guò)濾掉偶數(shù),我們當(dāng)然可以直接操作,比如:

            arr=[1,3,2,4,5,8]

            [iforiinarrifi%2>0]

            而使用filter會(huì)非常方便:

            list(filter(lambdax:x%2>0,arr))

            從這個(gè)例子當(dāng)中可能看不出便捷,但是有的時(shí)候判斷的條件可能非常復(fù)雜,我們判斷的邏輯不能簡(jiǎn)單地在list定義當(dāng)中表達(dá)出來(lái),這個(gè)時(shí)候使用filter則會(huì)容易得多。

            最后,我們?cè)倏匆粋€(gè)類似的用法。在itertools當(dāng)中有一個(gè)方法叫做compress,通過(guò)compress我們可以實(shí)現(xiàn)根據(jù)一個(gè)序列的條件過(guò)濾另一個(gè)序列。

            舉個(gè)簡(jiǎn)單的例子,假設(shè),我們有兩個(gè)數(shù)組:

            student=['xiaoming','xiaohong','xiaoli','emily']

            scores=[60,70,80,40]

            我們想要獲取所有考試及格的同學(xué)的list,如果用常規(guī)做法基本上免不了使用循環(huán),但是使用compress可以很方便地通過(guò)一行代碼實(shí)現(xiàn):

            fromitemtoolsimportcompress

            >>>pass=[i>60foriinscores]

            >>>print(pass)

            [False,True,True,False]

            >>>list(compress(student,pass))

            ['xiaohong','xiaoli']

            需要注意的是filter和compress返回的都是一個(gè)迭代器,我們要獲取它們的值,需要手動(dòng)轉(zhuǎn)換成list。

            雖然在日常的開發(fā)當(dāng)中不使用這三樣神器同樣可以工作,但是用上它們之后,會(huì)提升很多代碼的可讀性,節(jié)省很多無(wú)用的代碼。尤其是在面試的時(shí)候,很有可能就會(huì)給面試官留下不一樣的印象,也許結(jié)果也會(huì)不同。

            以上內(nèi)容為大家介紹了Python之map、reduce和filter,希望對(duì)大家有所幫助,如果想要了解更多Python相關(guān)知識(shí),請(qǐng)關(guān)注IT培訓(xùn)機(jī)構(gòu):千鋒教育。

            聲明:本站稿件版權(quán)均屬千鋒教育所有,未經(jīng)許可不得擅自轉(zhuǎn)載。
            10年以上業(yè)內(nèi)強(qiáng)師集結(jié),手把手帶你蛻變精英
            請(qǐng)您保持通訊暢通,專屬學(xué)習(xí)老師24小時(shí)內(nèi)將與您1V1溝通
            免費(fèi)領(lǐng)取
            今日已有369人領(lǐng)取成功
            劉同學(xué) 138****2860 剛剛成功領(lǐng)取
            王同學(xué) 131****2015 剛剛成功領(lǐng)取
            張同學(xué) 133****4652 剛剛成功領(lǐng)取
            李同學(xué) 135****8607 剛剛成功領(lǐng)取
            楊同學(xué) 132****5667 剛剛成功領(lǐng)取
            岳同學(xué) 134****6652 剛剛成功領(lǐng)取
            梁同學(xué) 157****2950 剛剛成功領(lǐng)取
            劉同學(xué) 189****1015 剛剛成功領(lǐng)取
            張同學(xué) 155****4678 剛剛成功領(lǐng)取
            鄒同學(xué) 139****2907 剛剛成功領(lǐng)取
            董同學(xué) 138****2867 剛剛成功領(lǐng)取
            周同學(xué) 136****3602 剛剛成功領(lǐng)取
            相關(guān)推薦HOT
            python字節(jié)碼和機(jī)器碼的區(qū)別

            機(jī)器碼,學(xué)名機(jī)器語(yǔ)言指令,有時(shí)也被稱為原生碼,是電腦的CPU可直接解讀的數(shù)據(jù)。字節(jié)碼是一種中間狀態(tài)(中間碼)的二進(jìn)制代碼(文件)。需要直譯器...詳情>>

            2023-11-07 16:05:10
            Python常用切片操作

            以列表:a=[0,1,2,3,4,5,6,7,8,9]為說(shuō)明對(duì)象1.取偶數(shù)位置>>>b=a[::2][0,2,4,6,8]2.取奇數(shù)位置>>>b=a[1::2][1,3,5,7,9]3.拷貝整個(gè)對(duì)象>...詳情>>

            2023-11-07 15:21:58
            Python集合類型

            python目前有兩種內(nèi)置集合類型,set和frozenset。Ⅰ、兩者區(qū)別set是可變的,沒(méi)有哈希值,其內(nèi)容可以使用add()和remove()這樣的方法來(lái)改變,所以...詳情>>

            2023-11-07 15:18:22
            Python之三目運(yùn)算

            python可通過(guò)if語(yǔ)句來(lái)實(shí)現(xiàn)三目運(yùn)算的功能,因此可以近似地把這種if語(yǔ)句當(dāng)成三目運(yùn)算符。作為三目運(yùn)算符的if語(yǔ)句的語(yǔ)法格式如下:(True_statemen...詳情>>

            2023-11-07 15:14:46
            Python之有妙用的__name__屬性

            前面說(shuō)了,py文件分兩種:用于執(zhí)行的程序文件和用于導(dǎo)入的模塊文件。當(dāng)直接使用pythona.py的時(shí)候表示a.py是用于執(zhí)行的程序文件,通過(guò)import/fro...詳情>>

            2023-11-07 14:56:46