4個python常用高階函式的使用方法

2022-06-06 05:06:09 字數 4451 閱讀 6969

1、map

python內建了map()函式,map()函式接受兩個引數,乙個是函式,乙個是iterable,map將傳入的函式依次作用到序列的每乙個元素上,並把結果作為新的iterator返回。

舉例說明,比如我們有乙個函式f(x)=x*2,要把這個函式作用在乙個list[1, 2, 3, 4, 5, 6, 7, 8, 9]上,就可以用map()實現。

>>> def f(x):

... return x*2

...

>>> r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])

>>> list(r)

[2, 4, 6, 8, 10, 12, 14, 16, 18]

map()傳入的第乙個引數是f,即函式物件本身。由於結果r是乙個iterator,iterator是惰性序列,因此通過list()函式讓它把整個序列都計算出來並返回乙個list。

你可能會想,不需要map()函式,寫乙個迴圈,也可以計算出結果:

l = 

for i in [1, 2, 3, 4, 5, 6, 7, 8, 9]:

print(l)

的確也可以,但是,從上面的迴圈**,能一眼看明白」把f(x)作用在list的每乙個元素並把結果生成乙個新的list「嗎?

所以,map()作為高階函式,事實上它把運算規則抽象了,因此,我們不但可以計算簡單的f(x)=x*2,還可以計算任意複雜的函式,比如把這個list所有的數字轉為字串:

>>> list(map(str,[1, 2, 3, 4, 5, 6, 7, 8, 9]))

['1', '2', '3', '4', '5', '6', '7', '8', '9']

只需要一行**就可以搞定。

2、reduce

再看reduce的用法。reduce是把乙個函式作用在乙個序列[x1, x2, x3……]上,這個函式必須接收兩個引數,reduce把結果繼續和序列的下乙個元素做累計計算。簡單來說,就是先計算x1和x2的結果,再拿結果與x3計算,依次類推。

reduce(f, [x1, x2, x3, x4]) = f(f(f(x1,x2), x3), x4)
比如說乙個序列求和,就可以用reduce實現。

>>> from functools import reduce

>>> def add(x, y):

... return x + y

...

>>> reduce(add, [1, 3, 5, 7, 9])

25

當然求和運算可以直接使用python內建函式sum(),沒必要動用reduce。

但是如果要把序列[1, 3, 5, 7, 9]變換為整數13579,reduce就可以派上用場:

>>> from functools import reduce

>>> def fn(x, y):

... return x * 10 + y

...

>>> reduce(fn, [1, 3, 5, 7, 9])

13579

這個例子本身沒多大用處,但是,如果考慮到字串str也是乙個序列,對上面的例子稍加改動,配合map,我們就可以寫出把str轉換為int的函式:

>>> from functools import reduce

>>> def fn(x, y):

... return x * 10 + y

...>>> def char2num(s):

... digits =

... return digits[s]

...>>> reduce(fn, map(char2num, '13579'))

13579

from functools import reduce

digits =

def str2int(s):

def fn(x, y):

return x * 10 + y

def char2num(s):

return digits[s]

return reduce(fn, map(char2num, s))

還可以用lambda函式進一步簡化成:

from functools import reduce

digits =

def char2num(s):

return digits[s]

def str2int(s):

return reduce(lambda x, y: x * 10 + y, map(char2num, s))

也就是說,假設python沒有提供int()函式,你完全可以自己寫乙個把字串轉化為整數的函式,而且只需要幾行**。

3、filter

python內建的filter()函式用於過濾序列。

和map()類似,filter()也接收乙個函式和乙個序列。和map()不同的是,filter()把傳入的函式依次作用於每乙個元素,然後根據返回值是true還是false決定保留還是丟棄該元素。

例如,在乙個list中,刪掉偶數,只保留奇數,可以這麼寫:

def is_odd(n):

return n % 2 == 1

list(filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15]))

# 結果: [1, 5, 9, 15]

把乙個序列中的空字串刪掉,可以這麼寫:

def not_empty(s):

return s and s.strip()

list(filter(not_empty, ['a', '', 'b', none, 'c', ' ']))

# 結果: ['a', 'b', 'c']

可見用filter()這個高階函式,關鍵在於正確實現乙個篩選函式。

注意到filter()函式返回的是乙個iterator,也就是乙個惰性序列,所有要強迫filter()完成計算結果,需要用list()函式獲得所有結果並返回list。

4、sorted

排序也是在程式中經常用到的演算法。無論使用氣泡排序還是快速排序,排序的核心是比較兩個元素的大小。如果是數字,我們可以直接比較,但如果是字串或者兩個dict呢?直接比較數學上的大小是沒有意義的,因此,比較的過程必須通過函式抽象出來。

python內建的sorted()函式就可以對list進行排序:

>>> sorted([36, 5, -12, 9, -21])

[-21, -12, 5, 9, 36]

此外,sorted()函式也是乙個高階函式,它還可以接收乙個key函式來實現自定義的排序,例如按絕對值大小排序:

>>> sorted([36, 5, -12, 9, -21], key=abs)

[5, 9, -12, -21, 36]

key指定的函式將作用於list的每乙個元素上,並根據key函式返回的結果進行排序。

我們再看乙個字串排序的例子:

>>> sorted(['bob', 'about', 'zoo', 'credit'])

['credit', 'zoo', 'about', 'bob']

預設情況下,對字串排序,是按照ascii的大小比較的,由於'z' < 'a',結果,大寫字母z會排在小寫字母a的前面。

現在,我們提出排序應該忽略大小寫,按照字母序排序。要實現這個演算法,不必對現有**大加改動,只要我們能用乙個key函式把字串對映為忽略大小寫排序即可。忽略大小寫來比較兩個字串,實際上就是先把字串都變成大寫(或者都變成小寫),再比較。

這樣,我們給sorted傳入key函式,即可實現忽略大小寫的排序:

>>> sorted(['bob', 'about', 'zoo', 'credit'], key=str.lower)

['about', 'bob', 'credit', 'zoo']

要進行反向排序,不必改動key函式,可以傳入第三個引數reverse=true:

>>> sorted(['bob', 'about', 'zoo', 'credit'], key=str.lower, reverse=true)

['zoo', 'credit', 'bob', 'about']

5、小結

高階函式的抽象能力是非常強大的,在**中善於利用這些高階函式,可以使我們的**變得簡潔明瞭。

Python常用高階函式

高階函式是在python中乙個非常有用的功能函式,所謂高階函式就是乙個函式可以用來接收另乙個函式作為引數,這樣的函式叫做高階函式。為了便於理解,我們從實際例子來看看函式當做引數被傳遞到另個函式是什麼樣的。我們把abs 函式賦值給了f變數,接下來你就可以像使用abs 函式本身那樣使用f變數了,區別只是...

python 函式4(遞迴 高階函式)

python 函式4 遞迴 高階函式 遞迴 在函式內部,可以呼叫其他函式。如果乙個函式在內部呼叫自身本身,這個函式就是遞迴函式。遞迴特性 1.遞迴必須有乙個明確的結束條件 2.每次進入更深一層遞迴時,問題規模相比上次遞迴都應有所減少 3.遞迴效率不高,遞迴層次過多會導致棧溢位 在計算機中,函式呼叫是...

python中5個常用的內建高階函式

python內建常用高階函式 一 函式式程式設計 1 map 函式 是 python 內建的高階函式,它接收乙個函式 f 和乙個 list,並通過把函式 f 依次作用在 list 的每個元素上,得到乙個新的 list 並返回 def add x return x x print map add,1 ...