今天給你們介紹幾個比較特殊的函數,他們具備函數式編程的特色,有人將它們視爲 Python 可進行 「函數式編程」 的見證,至於什麼是函數式編程,不是本篇文章的重點,感興趣的能夠去了解一下。老讀者可能都知道,我很是推崇 Python 的簡潔優雅,而今天的這幾個函數,有了它們,最大的好處就是可讓程序更簡潔,固然,沒有它們程序也能夠用其它方式實現。編程
lambda 是一個能夠只用一行就能解決問題的函數,讓咱們先看下面的例子:bash
>>> def add(x):
... x += 1
... return x
...
>>> numbers = range(5)
>>> list(numbers)
[0, 1, 2, 3, 4]
>>> new_numbers = []
>>> for i in numbers:
... new_numbers.append(add(i))
...
>>> new_numbers
[1, 2, 3, 4, 5]
複製代碼
在上面的這個例子中,函數 add() 充當了一箇中間角色,固然上面的例子也能夠以下實現:app
>>> new_numbers = [i+1 for i in numbers]
>>> new_numbers
[1, 2, 3, 4, 5]
複製代碼
首先我要說,上面的列表解析式實際上是很好用的,可是我恰恰要用 lambda 這個函數代替 add(x)
:函數式編程
>>> lamb = lambda x: x+1
>>> new_numbers = []
>>> for i in numbers:
... new_numbers.append(lamb(i))
...
>>> new_numbers
[1, 2, 3, 4, 5]
複製代碼
在這裏的 lamb 就至關於 add(x) ,lamb = lambda x : x+1
就至關於 add(x) 裏的代碼塊。下面再寫幾個應用 lambda 的小例子:函數
>>> lamb = lambda x,y : x + y
>>> lamb(1,2)
3
>>> lamb1 = lambda x : x ** 2
>>> lamb1(5)
25
複製代碼
由上面的例子咱們能夠總結一下 lambda 函數的具體使用方法:lambda 後面直接跟變量,變臉後面是冒號,冒號後面是表達式,表達式的計算結果就是本函數的返回值。性能
在這裏有一點須要提醒的是,雖然 lambda 函數能夠接收任意多的參數而且返回單個表達式的值,可是 lambda 函數不能包含命令且包含的表達式不能超過一個。若是你須要更多複雜的東西,你應該去定義一個函數。優化
lambda 做爲一個只有一行的函數,在你具體的編程實踐中能夠選擇使用,雖然在性能上沒什麼提高,可是看着舒服呀。ui
咱們在上面講 lambda 的時候用的例子,其實 map 也能夠實現,請看下面的操做:spa
>>> numbers = [0,1,2,3,4]
>>> map(add,numbers)
[1, 2, 3, 4, 5]
>>> map(lambda x: x + 1,numbers)
[1, 2, 3, 4, 5]
複製代碼
map 是 Python 的一個內置函數,它的基本格式是:map(func, seq)
。翻譯
func 是一個函數對象,seq 是一個序列對象,在執行的時候,seq 中的每一個元素按照從左到右的順序依次被取出來,塞到 func 函數裏面,並將 func 的返回值依次存到一個列表裏。
對於 map 要主要理解如下幾個點就行了:
1.對可迭代的對象中的每個元素,依次使用 fun 的方法(其實本質上就是一個 for 循環)。
2.將全部的結果返回一個 map 對象,這個對象是個迭代器。
咱們接下來作一個簡單的小題目:將兩個列表中的對應項加起來,把結果返回在一個列表裏,咱們用 map 來作,若是你作完了,請往下看:
>>> list1 = [1,2,3,4]
>>> list2 = [5,6,7,8]
>>> list(map(lambda x,y: x + y,list1,list2))
[6, 8, 10, 12]
複製代碼
你看上面,是否是很簡單?其實這個還看不出 map 的方便來,由於用 for 一樣也不麻煩,要是你有這樣的想法的話,那麼請看下面:
>>> list1 = [1,2,3,4]
>>> list2 = [5,6,7,8]
>>> list3 = [9,10,11,12]
>>> list(map(lambda x,y,z : x + y + z,list1,list2,list3))
[15, 18, 21, 24]
複製代碼
你看三個呢?是否是用 for 的話就稍顯麻煩了?那麼咱們在想若是是 四個,五個乃至更多呢?這就顯示出 map 的簡潔優雅了,而且 map 還不和 lambda 同樣對性能沒有什麼提升,map 在性能上的優點也是槓槓的。
filter 翻譯過來的意思是 「過濾器」,在 Python 中,它也確實是起到的是過濾器的做用。這個解釋起來略微麻煩,仍是直接上代碼的好,在代碼中體會用法是我在全部的文章裏一直在體現的:
>>> numbers = range(-4,4)
>>> list(filter(lambda x: x > 0,numbers))
[1, 2, 3]
複製代碼
上面的例子其實和下面的代碼是等價的:
>>> [x for x in numbers if x > 0]
[1, 2, 3]
複製代碼
而後咱們再來寫一個例子體會一下:
>>> list(filter(lambda x: x != 'o','Rocky0429'))
['R', 'c', 'k', 'y', '0', '4', '2', '9']
複製代碼
我在以前的文章中不少次都說過,個人代碼都是用 Python3 版本的。在 Python3 中,reduce 函數被放到 functools 模塊裏,在 Python2 中仍是在全局命名空間。
一樣我先用一個例子來跑一下,咱們來看看怎麼用:
>>> reduce(lambda x,y: x+y,[1,2,3,4])
10
複製代碼
reduce 函數的第一個參數是一個函數,第二個參數是序列類型的對象,將函數按照從左到右的順序做用在序列上。若是你還不理解的話,咱們下面能夠對比一下它和 map 的區別:
>>> list1 = [1,2,3,4]
>>> list2 = [5,6,7,8]
>>> list(map(lambda x,y: x + y,list1,list2))
[6, 8, 10, 12]
複製代碼
對比上面的兩個例子,就知道二者的區別,map 至關因而上下運算的,而 reduce 是從左到右逐個元素進行運算。
至此,我在上面介紹了四個函數,這些函數不只使得代碼更加的簡單,並且在 Python3 中也優化了它們的性能。因此若是你喜歡的話,盡能夠放心大膽的使用。
更多內容,歡迎關注公衆號「Python空間」,期待和你的交流。