談談python裡面那些高級函數

  • 2019 年 10 月 6 日
  • 筆記

談到python,我們就不得不說python裡面的一些黑魔法,例如我們的高階函數就是黑魔法其中之一。

高階函數是什麼?

簡而言之就是將一個函數作為參數傳到另一個函數A中,那麼這個函數A就是高階函數。(可接收其他函數作為參數的函數稱為高階函數)

我們來看一個簡單的小例子:

def func(a, list):      return [a(x) for x in list]      def double(x):      return 2 * x      print(func(double, [1, 3, 5, 7]))

上面的程式碼中,func 是一個高階函數,它接收兩個參數,第 1 個參數是函數,也就是我們定義的double函數,第 2 個參數是list,func 的功能是將函數 a 逐個作用於list上,生成一個新的數組。

我們在使用func函數的時候傳入的第一個參數是函數的名字,不需要括弧和其他的東西,只傳函數名即可。

下面我們來看看,python自帶了一些高階函數,他們分別是map,reduce,filter。除此之外還有一個很特別的函數叫匿名函數lambda。

在了解內置高階函數之前,我們先來看看lambda是個怎麼樣的東西。

就拿我們剛剛定義的double函數來說,它的功能是將傳入的參數整體乘2,對於這麼簡單的功能,我們可能都不需要用def來定義函數,這個時候我們使用lambda來快捷定義函數即可:

double = lambda x: 2 * x  print(double(3))

程式碼形式:

lambda 參數: 表達式

主要看來其實就是定義的時候換了一種方式,類似於定義一個表達式這樣,可以對這個表達式直接進行賦值。調用的時候還是一樣,函數的名字就是賦值的變數名。

當然,我們也可以在定義的時候直接調用,也能運算結果:

print((lambda x: 2 * x)(3))

lambda定義與使用如此方便就決定了它的使用場景會特別的多,一般的:當我們需要創建一些臨時的、小巧的函數時,就會使用lambda了。一般的,當我們使用高階函數的時候會經常和lambda函數一起聯用。

對於上面的高階函數我們可以使用lambda改寫:

a = func(lambda x: 2 * x, [1, 3, 5, 7])  print(a)

Tips:

  • 匿名函數本質上是一個函數,沒有函數名稱,因此使用匿名函數不用擔心函數名衝突;
  • 匿名函數一般適用於創建一些臨時性的,小巧的函數;

map函數

下面我們來看看MAP函數:

map函數的使用形式如下:

map(function, sequence)

function就是傳入的函數名,sequence就是需要被function函數處理元素組成的序列。 整個過程可以理解成如下:

sequence = [item1, item2, item3, item4, item5]  for i in sequence:      function(i)

我們來看看幾個例子:

map(lambda x: x**2, [1, 2, 3])

這是一個map對象(迭代器),我們可以通過將它結果輸出:

for i in map(lambda x: x**2, [1, 2, 3]):      print(i)

當然,我們也可以將map的結果直接轉化成list:

list(map(lambda x: x**2, [1, 2, 3]))

reduce函數

python3版本的reduce函數已經不再是內置函數了,它需要在functools模組中導入:

from functools import reduce

reduce函數的使用形式如下:

reduce(function, sequence[, initial])

先將 sequence 的前兩個 item 傳給 function,即 function(item1, item2),函數的返回值和 sequence 的下一個 item 再傳給 function,即 function(function(item1, item2), item3),如此迭代,直到 sequence 沒有元素,如果有 initial,則作為初始值調用。

reduece(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
a = reduce(lambda x, y: x*y, [1, 2, 3, 4, 5, 6])  print(a)

有一點需要注意的是reduce的傳入函數需要傳入兩個參數,例如上面的例子:我們先選取list中的前兩個元素進行lambda函數相乘,然後將相乘的結果再與第三個元素相乘,如此繼續下去,一直到整個list元素都被讀取為止。

reduce(lambda x, y: x * y, [1, 2, 3, 4])  # 相當於 ((1 * 2) * 3) * 4  reduce(lambda x, y: x * y, [1, 2, 3, 4], 5) # ((((5 * 1) * 2) * 3)) * 4  reduce(lambda x, y: x / y, [2, 3, 4], 72)  #  (((72 / 2) / 3)) / 4  reduce(lambda x, y: x + y, [1, 2, 3, 4], 5)  # ((((5 + 1) + 2) + 3)) + 4  reduce(lambda x, y: x - y, [8, 5, 1], 20)  # ((20 - 8) - 5) - 1  f = lambda a, b: a if (a > b) else b   # 兩兩比較,取最大值  reduce(f, [5, 8, 1, 10])

filter函數

filter 函數用於過濾元素,它的使用形式如下:

filter(function, sequnce)

解釋:將 function 依次作用於 sequnce 的每個 item,即 function(item),將返回值為 True 的 item 組成一個 List/String/Tuple (取決於 sequnce 的類型,python3 統一返回迭代器, 和map一樣) 返回。

其實簡單來說filter就是一個過濾器,篩選sequnce裡面有用的元素。整個過程類似如下:

sequence = [item1, item2, item3, item4, item5]  sequence2 = []  for i in sequence:      if function(i)==True:          sequence2.append(i)  print(sequence2)

我們來看一個例子:

def odd(x):      return x % 2  number = filter(odd,range(10))  print(number)                <filter object at 0x0000000002F58D68>      number = list(filter(odd,range(10)))  print(number)                [1, 3, 5, 7, 9]

換成lambda:

number = list(filter(lambda x: x%2,range(10)))  print(number)                [1, 3, 5, 7, 9]

以上就是我們在python3中常用也不常用的高階函數了,他們為函數式編程提供了不少便利,可使程式碼變得更簡潔,如果有需要用到的地方大家以後可以盡量去使用哦!

Exit mobile version