亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

廖雪峰Python教程筆記(五)

系統 1679 0

廖雪峰Python教程筆記(五)

  • 7 函數式編程
    • 高階函數
      • map/reduce
      • filter:用于過濾序列。
        • sorted排序算法
    • 返回函數:
    • 匿名函數
    • 裝飾器
    • 偏函數

7 函數式編程

函數是Python內建支持的一種封裝,我們通過把大段代碼拆成函數,通過一層一層的函數調用,就可以 把復雜任務分解成簡單的任務,這種分解可以稱之為面向過程的程序設計 。函數就是面向過程的程序設計的基本單元。

函數式編程 (請注意多了一個“式”字)——Functional Programming,雖然也可以歸結到面向過程的程序設計,但其思想更接近數學計算。

計算機(Computer)和計算(Compute)的概念:

  • 在計算機的層次上,CPU執行的是加減乘除的指令代碼,以及各種條件判斷和跳轉指令,所以,匯編語言是最貼近計算機的語言。
  • 而計算則指數學意義上的計算,越是抽象的計算,離計算機硬件越遠。

對應到編程語言,就是越低級的語言,越貼近計算機,抽象程度低,執行效率高,比如C語言;越高級的語言,越貼近計算,抽象程度高,執行效率低,比如Lisp語言。

函數式編程就是一種抽象程度很高的編程范式,純粹的函數式編程語言編寫的函數沒有變量,因此,任意一個函數,只要輸入是確定的,輸出就是確定的,這種純函數我們稱之為沒有副作用。而允許使用變量的程序設計語言,由于函數內部的變量狀態不確定,同樣的輸入,可能得到不同的輸出,因此,這種函數是有副作用的。

函數式編程的一個特點就是,允許把函數本身作為參數傳入另一個函數,還允許返回一個函數!
由于Python允許使用變量,因此, Python不是純函數式編程語言。

高階函數

高階函數英文叫Higher-order function

函數本身也可以賦值給變量,即:變量可以指向函數。
在這里插入圖片描述
在這里插入圖片描述
如果一個變量指向了一個函數,那么,可否通過該變量來調用這個函數?用代碼驗證一下:
在這里插入圖片描述
對于abs()這個函數,完全可以把函數名abs看成變量,它指向一個可以計算絕對值的函數!
廖雪峰Python教程筆記(五)_第1張圖片
因為abs這個變量已經不指向求絕對值函數而是指向一個整數10!

傳入函數
一個函數就可以接收另一個函數作為參數,這種函數就稱之為 高階函數。

一個最簡單的高階函數:
在這里插入圖片描述
廖雪峰Python教程筆記(五)_第2張圖片

map/reduce

Python內建了map()和reduce()函數。
map()函數接收兩個參數,一個是函數,一個是Iterable,map將傳入的函數依次作用到序列的每個元素,并把結果作為新的Iterator返回。
廖雪峰Python教程筆記(五)_第3張圖片
map()作為高階函數,事實上它把運算規則抽象了,因此,我們不但可以計算簡單的f(x)=x2,還可以計算任意復雜的函數,比如,把這個list所有數字轉為字符串:
在這里插入圖片描述

再看reduce的用法。reduce把一個函數作用在一個序列[x1, x2, x3, …]上,這個函數必須接收兩個參數,reduce把結果繼續和序列的下一個元素做累積計算,其效果就是
在這里插入圖片描述
廖雪峰Python教程筆記(五)_第4張圖片
廖雪峰Python教程筆記(五)_第5張圖片
考慮到字符串str也是一個序列,對上面的例子稍加改動,配合map(),我們就可以寫出把str轉換為int的函數:
廖雪峰Python教程筆記(五)_第6張圖片
還可以用lambda函數進一步簡化成:
廖雪峰Python教程筆記(五)_第7張圖片
假設Python沒有提供int()函數,你完全可以自己寫一個把字符串轉化為整數的函數,而且只需要幾行代碼!

filter:用于過濾序列。

filter()把傳入的函數依次作用于每個元素, 然后根據返回值是True還是False決定保留還是丟棄該元素。
例如,在一個list中,刪掉偶數,只保留奇數,可以這么寫:
廖雪峰Python教程筆記(五)_第8張圖片
把一個序列中的空字符串刪掉,可以這么寫:
廖雪峰Python教程筆記(五)_第9張圖片

sorted排序算法

如果是數字,我們可以直接比較,但如果是字符串或者兩個dict呢?直接比較數學上的大小是沒有意義的,因此,比較的過程必須通過函數抽象出來。
廖雪峰Python教程筆記(五)_第10張圖片
此外,sorted()函數也是一個高階函數,它還可以接收一個key函數來實現自定義的排序,例如按絕對值大小排序:
在這里插入圖片描述
key指定的函數將作用于list的每一個元素上,并根據key函數返回的結果進行排序。對比原始的list和經過key=abs處理過的list:
廖雪峰Python教程筆記(五)_第11張圖片
字符串排序的例子:
在這里插入圖片描述
默認情況下,對字符串排序,是按照ASCII的大小比較的,由于’Z’ < ‘a’,結果,大寫字母Z會排在小寫字母a的前面。

用sorted()排序的關鍵在于實現一個映射函數。

返回函數:

函數作為返回值:高階函數除了可以接受函數作為參數外,還可以把函數作為結果值返回。
實現一個可變參數的求和
廖雪峰Python教程筆記(五)_第12張圖片
但是,如果不需要立刻求和,而是在后面的代碼中,根據需要再計算怎么辦?可以不返回求和的結果,而是返回求和的函數:
廖雪峰Python教程筆記(五)_第13張圖片
當我們調用lazy_sum()時,返回的并不是求和結果,而是求和函數:
在這里插入圖片描述
調用函數f時,才真正計算求和的結果:
在這里插入圖片描述

閉包
注意到返回的函數在其定義內部引用了局部變量args,所以,當一個函數返回了一個函數后,其內部的局部變量還被新函數引用,所以,閉包用起來簡單,實現起來可不容易。

匿名函數

當我們在傳入函數時,有些時候,不需要顯式地定義函數,直接傳入匿名函數更方便。
在這里插入圖片描述
通過對比可以看出,匿名函數lambda x: x * x實際上就是:
在這里插入圖片描述
關鍵字lambda表示匿名函數,冒號前面的x表示函數參數。
匿名函數有個限制,就是只能有一個表達式,不用寫return,返回值就是該表達式的結果。

用匿名函數有個好處,因為函數沒有名字,不必擔心函數名沖突。此外,匿名函數也是一個函數對象,也可以把匿名函數賦值給一個變量,再利用變量來調用該函數

裝飾器

由于函數也是一個對象,而且函數對象可以被賦值給變量,所以,通過變量也能調用該函數。
廖雪峰Python教程筆記(五)_第14張圖片
函數對象有一個__name__屬性,可以拿到函數的名字:
廖雪峰Python教程筆記(五)_第15張圖片

現在,假設我們要增強now()函數的功能,比如,在函數調用前后自動打印日志,但又不希望修改now()函數的定義,這種在代碼運行期間動態增加功能的方式,稱之為“裝飾器”(Decorator)。

本質上,decorator就是一個返回函數的高階函數。所以,我們要定義一個能打印日志的decorator,可以定義如下:
廖雪峰Python教程筆記(五)_第16張圖片
觀察上面的log,因為它是一個decorator,所以接受一個函數作為參數,并返回一個函數。我們要借助Python的@語法,把decorator置于函數的定義處:
在這里插入圖片描述
調用now()函數,不僅會運行now()函數本身,還會在運行now()函數前打印一行日志:
在這里插入圖片描述
把@log放到now()函數的定義處,相當于執行了語句:
在這里插入圖片描述
由于log()是一個decorator,返回一個函數,所以,原來的now()函數仍然存在,只是現在同名的now變量指向了新的函數,于是調用now()將執行新函數,即在log()函數中返回的wrapper()函數。

偏函數

Python的functools模塊提供了很多有用的功能,其中一個就是偏函數(Partial function)。要注意,這里的偏函數和數學意義上的偏函數不一樣。

int()函數還提供額外的base參數,默認值為10。如果傳入base參數,就可以做N進制的轉換:
廖雪峰Python教程筆記(五)_第17張圖片
假設要轉換大量的二進制字符串,每次都傳入int(x, base=2)非常麻煩,于是,我們想到,可以定義一個int2()的函數,默認把base=2傳進去:
在這里插入圖片描述
這樣,我們轉換二進制就非常方便了:
在這里插入圖片描述
functools.partial就是幫助我們創建一個偏函數的,不需要我們自己定義int2(),可以直接使用下面的代碼創建一個新的函數int2:
廖雪峰Python教程筆記(五)_第18張圖片
所以,簡單總結functools.partial的作用就是,把一個函數的某些參數給固定住(也就是設置默認值),返回一個新的函數,調用這個新函數會更簡單。

注意到上面的新的int2函數,僅僅是把base參數重新設定默認值為2,但也可以在函數調用時傳入其他值:
在這里插入圖片描述
最后,創建偏函數時,實際上可以接收函數對象、*args和**kw這3個參數,當傳入:
在這里插入圖片描述
實際上固定了int()函數的關鍵字參數base,也就是:
在這里插入圖片描述
在這里插入圖片描述
當傳入:
在這里插入圖片描述
廖雪峰Python教程筆記(五)_第19張圖片


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 成年女人看片免费视频频 | 五月综合激情视频在线观看 | 久久久久久久国产精品影院 | 精品伊人 | 国产91成人 | 亚洲狠狠成人综合网 | 99视频福利 | 久久综合伊人 | 五月婷影院 | 四虎影视永久免费观看 | 日韩精品中文字幕视频一区 | 中国一级一级全黄 | 中文字幕综合网 | 女人一级一级毛片 | 色视频网 | 在线观看精品91老司机 | 亚洲一区二区三区免费观看 | 欧美综合图 | 国产日比视频 | 97免费观看| 黄色在线观看免费 | 狠狠色狠狠干 | 成人免费一级毛片在线播放视频 | 四虎免费在线播放 | 亚洲国产精品久久久天堂麻豆 | 97成人在线视频 | 久久久99精品免费观看精品 | 欧美色黄视频 | 一级毛片aa高清免费观看 | 成年男女免费视频网站 | 日韩成人精品视频 | 九九热最新 | 91亚洲精品国产自在现线 | 中文字幕在线观看日本 | 99久久精品费精品国产一区二 | 国产原创麻豆精品视频 | 久久国产精品久久精品国产 | 免费一区二区三区免费视频 | 国产成人在线看 | 亚洲色综合 | 欧美成人精品免费播放 |