python函數式編程之高階函數學習

來源:互聯網
上載者:User

標籤:結合   描述   概念   函數的參數   對象   object   特性   traceback   markdown   

基本概念

函數式編程,是一種抽象程度很高的編程範式,純粹的函數式程式設計語言編寫的函數沒有變數。因此,任意一個函數,只要輸入確定,輸出就確定的這種函數我們稱之為純函數,我們稱這種函數沒有副作用。而允許使用白變數的程式設計語言,由於函數內部的變數狀態是不確定的,同樣的輸入可能有不同的輸出,我們稱這種函數為有副作用的。
函數式編程的一個特點就是,允許把函數本身作為參數傳遞給另一個函數,還允許返回一個函數!
Python對函數式編程提供部分支援。由於Python允許使用變數,因此,Python不是純函數式程式設計語言。
(這部分內容摘抄與廖雪峰老師的部落格文章,自己也進行了學習)

高階函數
  • 變數可以指向函數

    #變數可以指向函數f = abs;print(abs(-10));#10print(f(-10));#10#在這裡用f和abs調用的結果和效果是一樣的

    說明變數f 已經指向了函數 abs本身。

  • 函數名也是變數
    函數名就是指向函數的變數。如:

    abs = 10;print(abs(-10));# Traceback (most recent call last):#   File "test01.py", line 164, in <module>#     print(abs(-10));# TypeError: ‘int‘ object is not callable

    abs已經被賦值10,是一個指向10的變數了,就不能通過abs(-10)來調用該函數了,因為abs這個變數已經不指向求絕對值函數了。

  • 傳入函數
    就是一個函數可以作為另一個函數的參數,這種函數稱為高階函數。

    #一個簡單的高階函數def add(x, y, f):    return f(x) + f(y);print(add(5, -6, abs));#11
map/reduce

python內建了map()和reduce()函數。

  • map()函數
    map函數接收兩個參數,一個是函數,一個是iterable(可迭代的對象),map將傳入的函數一次作用到序列的每個元素,並把結果作為新的iterator返回。

    #map()函數def f(x):    return x * x;r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9]);print(list(r));# [1, 4, 9, 16, 25, 36, 49, 64, 81]
  • reduce()函數
    該函數必須接收兩個參數,reduce把函數結果繼續和序列的下一個元素做累積計算。
    如:累加

    #reduce()函數from functools import reduce;def add1(x, y):    return x + y;print(reduce(add1, [1, 3, 5, 7, 9]));#25

    這並不是reduce的用武之地,當我們要把上面的數列變成整數13579時,reduce就排上用場了:

    def fn(x, y):    return x * 10 + y;print(reduce(fn, [1, 3, 5, 7, 9]));

    這個例子也沒什麼意義,但是當我們要把字串 str 轉換成int的函數時,就用上了reduce(結合map)。

filter()函數
  • filter
    python內建的filter函數用於過濾序列。和map類似也接收一個函數和一個序列,但是不同的是,filter把傳入的函數依次作用於每個元素,然後根據傳回值是true還是false決定保留還是丟棄該元素。
    在一個list中,刪掉偶數,只保留奇數:

    #filter函數#在一個list中刪除偶數,只保留奇數def is_odd(n):    return n % 2 == 1;print(list(filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15])));# 1, 5, 9, 15
  • 用filter求素數
    思想:計算素數的一個方法是埃氏篩法,它的演算法理解起來非常簡單:

  1. 首先,列出從2開始的所有自然數,構造一個序列:

    2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...
  2. 取序列的第一個數2,它一定是素數,然後用2把序列的2的倍數篩掉:

    3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...
  3. 取新序列的第一個數3,它一定是素數,然後用3把序列的3的倍數篩掉:

    5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...
  4. 取新序列的第一個數5,然後用5把序列的5的倍數篩掉:

    7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...

不斷篩下去,就可以得到所有的素數。
註明:該演算法描述來源於廖雪峰老師的文章。

sorted()函數

排序演算法

#sorted函數排序print(sorted([36, -2, 5, 7, 1, -10]));# [-10, -2, 1, 5, 7, 36];

sorted也是一個高階函數,可以接受一個key函數來實現自訂的排序,列如按絕對值大小排序:

#sorted函數排序print(sorted([36, -2, 5, 7, 1, -10], key=abs));# [1, -2, 5, 7, -10, 36]

sorted函數可以用來對字串進行排序。
sorted()也是一個高階函數。用sorted()排序的關鍵在於實現一個映射函數。

總結

對函數式編程的學習這部分比較重要,學習這部分讓我想到了前端架構reactJs,react也是強調函數式編程的,也是react的特性。就是說一個函數可可以作為另一個函數的參數。上面的學習例子都是很簡單的,需要自己不斷的練習。

python函數式編程之高階函數學習

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.