Python 函數(shù)編編程的三大法寶map+filter+reduce分享
眾所周知,Python 支持多種編程范式:過程式(使用基礎(chǔ)的語句)、面向?qū)ο缶幊毯秃瘮?shù)式編程。
Python 也提供了其他函數(shù)式編程語言的工具:
- 利用 map 在一個可迭代對象的各項上調(diào)用函數(shù)的工具
- 利用 filter 來過濾項
- 利用 reduce 把函數(shù)作用在成對的項上來運行結(jié)果的工具
一、map
在沒有循環(huán)的情況下處理可迭代對象:map
有時我們需要對列表、集合、字典等可迭代序列做的一個操作就是:對其中每一個元素值進行某種操作,把其結(jié)果收集起來。
比如選出數(shù)據(jù)庫中的某一列進行加減操作,或者針對某些特殊的值做平方的處理。
我們先來看一個例子:
>>> test = [1, 2, 3, 4, 5, 6] >>> square = [] >>> for x in test: ? ? square.append(x*x) ? ?? >>> square [1, 4, 9, 16, 25, 36] >>>
此時就可以利用 Python
的 map
,允許您在不使用循環(huán)的顯式中處理和轉(zhuǎn)換所有項目,該技術(shù)通常稱為映射。當您需要將轉(zhuǎn)換函數(shù)應(yīng)用于可迭代并將其轉(zhuǎn)換為新的迭代時,map 就能夠有其用武之地。
>>> test = [1, 2, 3, 4, 5, 6] >>>? >>> def square(num): ? ? return num*num >>> list(map(square, test)) [1, 4, 9, 16, 25, 36] >>>
如上,我們會傳入一個自定義的函數(shù) ??square()??
來更加一般化地使用它,也就是對列表中的每一個元素都應(yīng)用這個函數(shù)。
map 對列表中的每一個元素都調(diào)用了 square
函數(shù),并將返回值收集到一個新的列表中。
正因為我們需要自定義一個 square 函數(shù),結(jié)合上一篇文章 ? ?lambda
函數(shù)??的簡單介紹中。我們可以利用 lambda 直接生成這個匿名函數(shù),也就是可以寫出這樣的代碼實現(xiàn)相同的功能:
>>> list(map((lambda x: x*x), test)) [1, 4, 9, 16, 25, 36] >>>
map 傳入內(nèi)置 Python 函數(shù)
除了自定義函數(shù),還可以 map 中傳入內(nèi)置的 Python 函數(shù)。例如,如果您有一個字符串列表,您可以輕松地創(chuàng)建一個計算該字符串列表長度的新列表:
>>> name = ["Sam", "Dwen", "Kyrie"] >>> list(map(len, name)) [3, 4, 5] >>>
map 高級用法
map 不單能實現(xiàn) for 循環(huán)能實現(xiàn)的同樣的方式,還有性能優(yōu)勢。map 的高級用法比如:在一個可序列類型中,map 會按照順序,并行地從各個序列中逐項取出一組又一組參數(shù),然后傳入函數(shù)中:
>>> pow(2, 8) 256 >>> pow(3,8) 6561 >>> list(map(pow, [1,2,3], [8, 8, 8])) [1, 256, 6561] >>>
能看到上述代碼的結(jié)果,map 對傳入的每個序列并行各自取一個值。
二、map 與列表推導式
map 調(diào)用其實與列表推導式相似。
>>> test = [1, 2, 3, 4, 5, 6] >>> [x*x for x in test] [1, 4, 9, 16, 25, 36] >>> list(map((lambda x: x*x), test)) [1, 4, 9, 16, 25, 36]
但是 map 在一般情況下會比列表推導式運行更快,而且編寫的代碼也會更少。而且有一點很重要:通過使用圓括號而不是方括號來包圍一個推導,能創(chuàng)建一個按需產(chǎn)生值的對象,減少了內(nèi)存又減少了程序的響應(yīng)時間。
三、選擇可迭代對象中的元素:filter
map 函數(shù)是將 Python 函數(shù)式編程工具集中一個主要也相對明確的代表。而 filter 和 reduce 分別實現(xiàn)了基于一個測試函數(shù)選擇可迭代對象的元素,以及向”元素對“ 應(yīng)用函數(shù)的功能。
下面來看一個調(diào)用 filter 挑出一個序列中大于零的元素:
>>> list(range(-10, 10)) [-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> list(filter((lambda x : x > 0), range(-10, 10))) [1, 2, 3, 4, 5, 6, 7, 8, 9]
filter 對于序列或可迭代對象中的元素,如果函數(shù)對該元素返回了 True 值,這個元素就會被加入到結(jié)果列表中。
與 map 一樣,filter 也能用一個 for 循環(huán)來等效,但是 filter 是內(nèi)置的、簡明的,通常也運行得更快:
>>> result = [] >>> for x in range(-10, 10): ? ? if x > 0: ? ? ? ? result.append(x) ? ? ? ?? >>> resullt [1, 2, 3, 4, 5, 6, 7, 8, 9]
同樣的功能,我們也能用列表推導式來實現(xiàn):
>>> [x for x in range(-10,10) if x > 0] [1, 2, 3, 4, 5, 6, 7, 8, 9]
四、合并可迭代對象中的元素: reduce
Python的 reduce()
是一種函數(shù),它在 Python 標準庫中居住在一個名為 ??functools?? 的模塊中:
from functools import reduce
通過 reduce 來計算一個列表中所有元素加起來的和:
>>> reduce((lambda x, y: x + y),[1,2,3,4,5]) 15
reduce
會將當前的和列表中的下一個元素傳入列出的 lambda 函數(shù),在默認條件下,序列中的第一個元素初始化了起始值。
使用 reduce 的這種用法也與如下使用 for 循環(huán)實現(xiàn)了同樣的功能:
>>> test = [1, 2, 3, 4, 5] >>> result = test[0] >>> for x in test[1:]: ? ? result ?= result + x ? ?? >>> result 15
五、總結(jié)
- map 包括將轉(zhuǎn)換函數(shù)應(yīng)用于可迭代對象以生成新的可迭代對象。新迭代中的項是通過對原始迭代中的每個項調(diào)用轉(zhuǎn)換函數(shù)來生成的。
- filter 包括將謂詞或布爾值函數(shù)應(yīng)用于迭代以生成新的可迭代。通過篩選原始可迭代中的任何項目,以使謂詞函數(shù)返回 false 的任何項目生成的項目。
- reduce 包括將 reduce 函數(shù)應(yīng)用于迭代以產(chǎn)生單個累積值。
到此這篇關(guān)于Python 函數(shù)編編程的三大法寶map+filter+reduce分享的文章就介紹到這了,更多相關(guān)Python 法寶map+filter+reduce內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
pymssql數(shù)據(jù)庫操作MSSQL2005實例分析
這篇文章主要介紹了pymssql數(shù)據(jù)庫操作MSSQL2005的方法,可實現(xiàn)基本的連接、查詢、插入、更新及調(diào)用存儲過程等功能,非常具有實用價值,需要的朋友可以參考下2015-05-05tensorflow獲取預訓練模型某層參數(shù)并賦值到當前網(wǎng)絡(luò)指定層方式
今天小編就為大家分享一篇tensorflow獲取預訓練模型某層參數(shù)并賦值到當前網(wǎng)絡(luò)指定層方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-01-01如何使用Python JSON解析和轉(zhuǎn)換數(shù)據(jù)
JSON 是文本,使用 JavaScript 對象表示法編寫,Python 有一個內(nèi)置的 json 包,可用于處理 JSON 數(shù)據(jù),本文給大家介紹使用Python JSON解析和轉(zhuǎn)換數(shù)據(jù)的方法,感興趣的朋友跟隨小編一起看看吧2023-11-11django項目環(huán)境搭建及在虛擬機本地創(chuàng)建django項目的教程
這篇文章主要介紹了django項目環(huán)境搭建及在虛擬機本地創(chuàng)建django項目的教程,本文圖文并茂給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2019-08-08