高等函數


高階函數

接受函數為參數,或者把函數作為結果返回的函數是高階函數(high-order function)。map函數就是一個,內置函數sorted也是:可選的key參數用於提供一個函數,它會應用到各個元素上進行排序

# 根據單詞長度給一個列表排序
fruits = ['strawbery', 'fig', 'apple', 'cherry', 'respberry', 'banana']
sorted(fruits, key=len)
['fig', 'apple', 'cherry', 'banana', 'strawbery', 'respberry']

任何單參數函數都能作為key參數的值。例如,為了創建押韻詞典,可以把各個單詞反過來拼寫,然后排序。但是列表中的單詞沒有變,只是把反向拼寫當作排序條件,因此berry都排在一起

# 根據反向拼寫給一個單詞列表排序
def reverse(word):
    return word[::-1]


reverse('testing')
'gnitset'
sorted(fruits, key=reverse)
['banana', 'apple', 'fig', 'strawbery', 'respberry', 'cherry']

在函數式編程范式中,最為人熟知的高階函數有map、filter、reduce和apply。apply函數在Python3中移除了,因為不再需要它了。如果想使用不定量的參數調用函數,可以編寫fn(*args,**keywords),不用再編寫apply(fn,args,kwargs)

map、filter和reduce的現代替代品

函數式語言通常會提供map、filter和reduce三個高階函數(有時使用不同的名稱)。在Python中,map和filter還是內置函數,但是由於引入了列表推導和生成器表達式,它們變得沒那么重要了。列表推導或生成器表達式具有map和filter兩個函數的功能,而且更易於閱讀

# 計算階乘列表:map和filter與列表推導比較
def factorial(n):
    return 1 if n < 2 else n * factorial(n - 1)


fact = factorial
list(map(fact, range(6))) # 構建0!到5!的一個階乘列表
[1, 1, 2, 6, 24, 120]
[fact(n) for n in range(6)] # 使用列表推導式執行相同的操作
[1, 1, 2, 6, 24, 120]
list(map(fact, filter(lambda n: n % 2, range(6)))) # 使用map和filter計算直到5!的奇數階乘列表。
[fact(n) for n in range(6) if n % 2] # 使用列表推導做相同的工作,換掉map和filter,並避免了使用lambda表達式
[1, 6, 120]

在Python3中,map和filter返回生成器(一種迭代器),因此現在它們的直接替代品是生成器表達式(在Python2中,這兩個函數返回列表,因此最接近的替代品是列表推導)

在Python2中,reduce是內置函數,但是在Python3中放到functools模塊里。這個函數最常用於求和,自2003年發布的Python2.3開始,最好使用內置的sum函數。在可讀性和性能方面,這是一項重大改善

# 使用reduce和sum計算0~99之和
from functools import reduce # 從Python3.0開始,reduce不再是內置函數
from operator import add # 導入add,以免創建一個專求兩數之和的函數
reduce(add,range(100)) # 計算0~99之和
4950
sum(range(100)) # 使用sum做相同的求和;無需導入和創建求和函數
4950

sum和reduce的通用思想是把某個操作連續應用到序列的函數上,累計之前的結果,把一系列值規約成一個值

all和any也是內置的歸約函數

all(iterable) 如果iterable的每個元素都是真值,返回True;all([])返回True

any(iterable) 只要iterable中有元素是真值,就返回True;any([])返回False


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM