談談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中常用也不常用的高階函數了,他們為函數式編程提供了不少便利,可使程式碼變得更簡潔,如果有需要用到的地方大家以後可以盡量去使用哦!