<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Python入門系列28 - 進(jìn)階必修之匿名函數(shù)與高階函數(shù)

          共 2474字,需瀏覽 5分鐘

           ·

          2019-12-19 23:22

          Python入門系列28

          8d8bfedaff336a33392f534d61517f5c.webp

          進(jìn)階必修之匿名函數(shù)與高階函數(shù)


          本篇閱讀時間約為 7 分鐘。


          1

          前言


          嗨!大家好哇,讓我們繼續(xù)回歸Python入門系列之路,本章為進(jìn)階篇,介紹的是匿名函數(shù)與高階函數(shù)。


          2

          匿名函數(shù)之 lambda 表達(dá)式


          見名知意,所謂的匿名函數(shù)就是沒有名字的函數(shù)。我們平時所寫的函數(shù)都是帶有名字和參數(shù)的,并且有返回值,而匿名函數(shù)的寫法卻非常簡潔,對于初學(xué)者而言,代碼的閱讀性可能會較差一些,但是多加實踐,看習(xí)慣了之后就能明白所謂的lambda表達(dá)式是什么意思了!接下來還是用示例說話,場景是這樣的:有個函數(shù),傳入兩個參數(shù)a和b,在函數(shù)內(nèi)部將他們做差,并將結(jié)果返回。


          示例1 - 普通函數(shù):


          def?sub(a,?b):
          ????return?a?-?b

          result?=?sub(1,?2)
          print(result)

          >>>?-1


          示例2 - 匿名函數(shù):


          sub?=?lambda?a,?b:?a?-?b
          result?=?sub(1,?2)
          print(result)


          142471a3e35fd45905446743dee12333.webp

          解釋一下上面的案例,使用 python 中的 lambda 關(guān)鍵詞來定義匿名函數(shù),參數(shù)在冒號前面,表達(dá)式在冒號后面,將整個 lambda 表達(dá)式賦予一個變量sub,通過調(diào)用sub傳入?yún)?shù)得到結(jié)果result,與普通函數(shù)得到一致的結(jié)果。


          匿名函數(shù)的寫法,通過關(guān)鍵詞 lambda 來表示匿名,基于數(shù)學(xué)中的λ演算得名。lambda表達(dá)式完整的寫法公式如下:


          lambda?parameter_list?:?expression


          什么意思呢?通過 lambda 后面跟上傳入的參數(shù),加上冒號,以及冒號后面的表達(dá)式組成了匿名函數(shù),注意:冒號后面一定要是表達(dá)式!


          表達(dá)式意味著,如果我們寫成賦值語句或者for循環(huán)語句等非表達(dá)式語句,那么 lambda 表達(dá)式則會報錯!如下:

          9166155d9c8f5a017cd42650569dba82.webp


          所以由此引出了匿名函數(shù) lambda 中常用的三元表達(dá)式


          示例3 - Python的三元表達(dá)式:

          假設(shè)現(xiàn)在有兩個變量,a = 1,b = 2,請使用一行代碼來判斷 a 小于 b ,若 a 小于 b 為真,則將 a 的值返回。


          a?=?1
          b?=?2
          result?=?a?if?a?else?b
          print(result)


          09129ffcfa5442c61cebdc51fa56853d.webp

          result 這一行就是所謂的 Python 中的三元表達(dá)式,用中文描述一下就是:

          條件為真時返回的結(jié)果?if?條件判斷?else?條件為假時返回的結(jié)果


          3

          高階函數(shù)


          高階函數(shù),Python中自帶了一些高階特性的函數(shù),在某些特定場景下非常實用,這里舉幾個常用的,當(dāng)然也會結(jié)合具體場景去說,畢竟要結(jié)合使用不能濫用!


          1. map 函數(shù)

          map 函數(shù),map中文意思是地圖的意思,但是在程序中代表映射的意思。高中學(xué)過的映射,不知大家是否還記得!跟那個意思差不多。。。


          場景如下:現(xiàn)在有一個 list_a ,它其中的包含著 1~6 的數(shù)字,請將此集合中的數(shù)字都乘以 2 ,最終得到的結(jié)果組成一個新的 list_b。


          list_a?=?[1,?2,?3,?4,?5,?6]
          xxxxx
          得到 list_b


          不使用 map ,你會怎么做呢?思考一下,然后再看下面的答案:

          list_a?=?[1,?2,?3,?4,?5,?6]
          list_b?=?[]

          def?double_fun(a):
          ????return?2?*?a

          for?a?in?list_a:
          ????list_b.append(double_fun(a))

          print(list_b)


          fff00ca2cb94b62e396ac26040786a86.webp

          通過 for 循環(huán)取出?list?每個值,在對其調(diào)用乘2的函數(shù),最后將結(jié)果進(jìn)行拼接,得到 list_b 。


          使用 map 函數(shù)之前,先了解下 map 函數(shù)語法:

          map(function, iterable,...)

          map()?會根據(jù)提供的函數(shù)對指定序列做映射。

          第一個參數(shù) function 以參數(shù)序列中的每一個元素調(diào)用 function 函數(shù),返回包含每次 function 函數(shù)返回值的新列表。


          list_a?=?[1,?2,?3,?4,?5,?6]

          def?double_fun(a):
          ????return?2?*?a

          result?=?map(double_fun,?list_a)
          print(result)
          print(type(result))
          print(list(result))


          d960b1a1021e4e2544c30a02b87d928f.webp


          可以看到,素質(zhì)三連print!得到的結(jié)果,map返回的結(jié)果是一個 map 對象,而它本身的類型就是 map,將其轉(zhuǎn)化為 list,可以得到與不用 map 函數(shù)時的一樣結(jié)果!


          實際上,如果會活學(xué)活用的話,還可以將上述代碼進(jìn)行縮減,用我們剛學(xué)過的 lambda 表達(dá)式來完成!


          list_a?=?[1,?2,?3,?4,?5,?6]


          #?def?double_fun(a):
          #?????return?2?*?a

          result?=?map(lambda?a:?2?*?a,?list_a)
          print(list(result))


          將普通函數(shù)注釋掉,使用匿名函數(shù)來完成,實際上就3行代碼即可完成,如下:

          b1ee604d819d8b7f33f7cfc93545fe15.webp


          如果有多個參數(shù)作為匿名函數(shù)的入?yún)⑷绾螌懩兀?/span>

          可以使用 pycharm 自帶的源碼查看功能,查看 map 函數(shù)的定義,按住 Ctrl 點擊 map 即可:

          7fed258949df2bb97c5db956a9984ca4.webp


          map 第一個參數(shù)傳入函數(shù)名稱,第二個傳入的是一個可以迭代的對象,例如list,而用紅框標(biāo)出來的其中包括了一個 * 號,在Python中參數(shù)前面跟一個星號代表多個形參的意思。所以我們可以寫法如下,當(dāng)有兩個相同 list 時,多次傳入 map 函數(shù)中即可:


          list_a?=?[1,?2,?3,?4,?5,?6]
          list_b?=?[1,?2,?3,?4,?5,?6]
          result?=?map(lambda?a,?b:?2?*?a?+?2?*?b,?list_a, list_b)
          print(list(result))


          d2caf350443a61d852bad15e8b2cf3b3.webp


          現(xiàn)在是相同的個數(shù)的 list ,如果要是不同個數(shù)內(nèi)容的 list 會如何?做個實驗,將 list_b 的個數(shù)改為 10 個觀察下:


          list_a?=?[1,?2,?3,?4,?5,?6]
          list_b?=?[1,?2,?3,?4,?5,?6,?7,?8,?9,?10]
          result?=?map(lambda?a,?b:?2?*?a?+?2?*?b,?list_a,?list_b)
          print(list(result))


          98e5c01680419a4029b8bad37aed58ce.webp


          可以看到,即使兩個不同內(nèi)容的list進(jìn)行map計算,最終結(jié)果也會根據(jù)內(nèi)容少的list得到最終結(jié)果,也就是只進(jìn)行前6位的計算。


          2. reduce 函數(shù)

          reduce 函數(shù)不能直接進(jìn)行引用,在 Python3 中,reduce() 函數(shù)已經(jīng)被從全局命名空間里移除了,它現(xiàn)在被放置在 functools 模塊里,如果想要使用它,則需要通過引入 functools 模塊來調(diào)用 reduce() 函數(shù),還是先來看下 reduce 函數(shù)的語法使用:

          reduce(function, iterable[, initializer])

          function -- 函數(shù),有兩個參數(shù)

          iterable -- 可迭代對象

          initializer -- 可選,初始參數(shù)


          函數(shù)將一個數(shù)據(jù)集合(鏈表,元組等)中的所有數(shù)據(jù)進(jìn)行下列操作:用傳給 reduce 中的函數(shù) function(有兩個參數(shù))先對集合中的第 1、2 個元素進(jìn)行操作,得到的結(jié)果再與第三個數(shù)據(jù)用 function 函數(shù)運(yùn)算,最后得到一個結(jié)果。


          老規(guī)矩,點進(jìn)去看源碼,其中有官方的文檔注釋:

          52f55a32fcdb3b8c5ebfc88fbcc16fa0.webp

          咱們就用它注釋中的例子來實踐一下,作為 reduce 的第一個函數(shù),入?yún)⒈仨毷莾蓚€參數(shù),否則會報錯,例如下面:

          c105a3d9fdefa3f2f62cb3fc4359256a.webp


          改成官方例子:

          from?functools?import?reduce

          result?=?reduce(lambda?x,?y:?x?+?y,?[1,?2,?3,?4,?5])
          print(result)
          print(type(result))


          cabf922007586d6737475bfe2022e12c.webp


          素質(zhì)二連,print出結(jié)果,可以看到這次與 map 函數(shù)不同,返回的結(jié)果是一個計算后的整數(shù) 15 !這個 reduce 函數(shù)是怎么算出來的呢?仔細(xì)看過注釋的同學(xué)一定知道怎么來的了,實際上就是這樣來的:


          ?reduce(lambda?x,?y:?x+y,?[1,?2,?3,?4,?5])??--->??((((1+2)+3)+4)+5)


          第一次計算時,x = 1,y = 2,于是將 1 + 2 = 3 的結(jié)果作為下一次調(diào)用時入?yún)⒌膞,而第二次計算時的 y 則是列表中的數(shù)字3 ......以此類推

          (1+2) --> ((1+2)+3) --> ....? -->?((((1+2)+3)+4)+5)


          reduce 函數(shù)是一個連續(xù)計算的函數(shù)!


          再來看下 reduce 函數(shù)的第三個參數(shù),初始化第一個入?yún)⒅担?/span>

          from?functools?import?reduce

          result?=?reduce(lambda?x,?y:?x?+?y,?[1,?2,?3,?4,?5],?10)
          print(result)


          833ad508604521cae7f11f69ef0766af.webp

          這個計算的順序則是第一次 x = 10,y = 1,將 x+y 的值 11 賦予第二次計算的 x 作為入?yún)ⅲ诙斡嬎銜r的 y = 2,第二次計算結(jié)果等于 11 + 2 = 13 .... 以此類推。

          (10+1) -->?(10+1)+2) -->?((10+1)+2)+3) .... --> ((((10+1)+2)+3)+4)+5)


          3. filter 函數(shù)

          filter 函數(shù),這個英文單詞的中文含義是過濾的意思。依然是看下官方語法:

          filter(function, iterable)

          function -- 判斷函數(shù)。

          iterable -- 可迭代對象。


          filter() 函數(shù)用于過濾序列,過濾掉不符合條件的元素,返回由符合條件元素組成的新列表。

          該接收兩個參數(shù),第一個為函數(shù),第二個為序列,序列的每個元素作為參數(shù)傳遞給函數(shù)進(jìn)行判,然后返回 True 或 False,最后將返回 True 的元素放到新列表中。


          示例,請將下面的 list 中為小寫字母的字符串提取出來,生成一個新的列表:


          list_word?=?['a',?'A',?'B',?'c',?'D',?'E',?'f']


          思考一下再看答案喲:


          list_word?=?['a',?'A',?'B',?'c',?'D',?'E',?'f']
          result?=?filter(lambda?word:?word?if?word.islower()?else?False,?list_word)
          print(result)
          print(list(result))

          >>>?0x000001D82D743080>
          >>>?['a',?'c',?'f']


          7d18939e928e69d0809bebf38b01437d.webp

          結(jié)果如上圖,通過字符串的自帶函數(shù),islower() 可以判斷字符串是否是小寫字母,若是小寫字母則返回一個 True ,可以看到筆者的 lambda 表達(dá)式用了一個三元表達(dá)式的寫法,來過濾掉了原列表的大寫字母,是不是很簡潔呢!畢竟人生苦短,我用Python啊!


          4

          map - reduce 擴(kuò)展知識


          map / reduce 實際上是大數(shù)據(jù)中的一個編程模型,其中 map 代表映射的意思,reduce 代表歸約的意思,而這個模型主要是用來進(jìn)行并行計算的!可以用一張圖來看生動的看下 hadoop (Hadoop是一個由Apache基金會所開發(fā)的分布式系統(tǒng)基礎(chǔ)架構(gòu)。)中的 map / reduce:


          13b72de716a0da73a0cd5228ab1f9fdd.webp

          做三明治,用到了各種蔬菜,首先我們先將每個蔬菜切碎,通過map 映射成碎片,在使用 reduce 進(jìn)行并行計算使之合體!


          5

          總結(jié)


          說一些學(xué)習(xí)上的技巧,對于一個新的函數(shù),首先學(xué)習(xí)看它的語法,第一時間可以去找官方文檔看,比如點進(jìn)去看它的官方注釋,如果英文看不懂的話呢,可以去菜鳥教程上搜下,上面也是有不少官方文檔的定義,都是中文教程。寫到現(xiàn)在,大部分Python小課堂上的小實例都是非常簡單的,入門與進(jìn)階通俗易懂,但是不要小瞧這些小 demo ,如果你真的把它們都弄明白了,就像前期種下一顆種子一樣,穩(wěn)定根基之后必將作為長成參天大樹的必要前提!


          至此完!

          9856f6341f575bc1c17c7eb59b794b41.webp


          瀏覽 73
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  不卡的av天天在线影院 | 一起操视频网站 | 大香蕉国产伊人视频 | 水蜜桃獊传媒视频 | 亚洲人7777 |