Python 函數式編程入門教程
點擊上方「
Python開發
」,選擇「置頂公眾號」
關鍵時刻,第一時間送達!
引言
Functional Programming(函數式編程)的概念最早起源於LISP,由約翰·麥卡錫在1958年創立,最早提出了自動垃圾回收的理念,這一理念現在也被Python/Java/Ruby等多種語言借鑒。發展到今天,LISP已經衍生出了多種方言。相比面向對象編程,函數式編程的一大優勢就是Immutable Data(數據不可變),就是
不依賴於外部的數據,而且也不改變外部數據的值
,這種思想可以大大減少我們代碼的Bug,而且函數式編程也支持我們像使用變數一樣使用函數
。Python作為面向對象語言,也提供了對於函數式編程的支持,雖然並不是那麼純粹,而且也不支持尾遞歸優化。lambda的使用
lambda即匿名函數,合理地使用lambda不僅可以減少我們的代碼量,而且也可以更好地描繪代碼邏輯,比如現在我們有下面這樣一個函數。
>>>
def
f
(
x
)
:
...
return
x
+
x
# 調用這個函數
>>>
f
(
2
)
4
這個函數如果我們用lamda改寫的話,只要一行代碼就夠了。
# lambda後面的x表示lambda函數要接收的參數,x + x表示lambda函數所要返回的值
>>>
f
=
lambda
x
:
x
+
x
# 可以看到f現在也是一個函數對象
>>>
f
<
function __main__
.
<
lambda
>>
# 調用lambda函數
>>>
f
(
2
)
4
map的使用
map(function, iterable)接收兩個參數,第一個參數代表的是
接收一個函數
,第二個參數代表的是接收一個iteralbe類型的對象,比如list
。map函數的原理是: 1.每次從iterable中取出一個參數,2.將這個參數傳遞給我們的函數,3.然後函數返回的值加入一個list(這種說法不準確,只是為了幫助大家理解,後面我會解釋)。等所有的iterable對象遍歷完,map就把這個list返回給我們的調用者。下面我們直接通過實例來了解一下map的用法。
example1
# 還是用我們上面那個lambda的例子
>>>
function
=
lambda
x
:
x
+
x
# 定義一個iterable對象list(列表)
>>>
iterable
=
[
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
]
# 函數fucntion每次從iterable中取出一個參數x,然後function返回x + x的值,
# 並將返回值加入一個新建的list,等將iterable遍歷完,map就將這個新建的list返回。
>>>
v
=
map
(
function
,
iterable
)
# 注意上面的說法並不準確,只是為了幫助大家理解,其實map返回的是一個map對象,並不是list
>>>
v
<
map
at
0x7fcb56231588
>
# 但是我們可以調用內建的list函數將map轉換成一個list來得到我們想要的結果
>>>
list
(
v
)
[
2
,
4
,
6
,
8
,
10
,
12
,
14
,
16
,
18
]
example2
對於map的第二個參數,我們也可以傳遞一組函數列表進去,也就是說列表中間包含多個函數對象。
>>>
multiply
=
lambda
x
:
x
*
x
>>>
add
=
lambda
x
:
x
+
x
>>>
funcs
=
[
multiply
,
add
]
>>>
list
(
map
(
lambda
f
:
f
(
1
),
funcs
))
[
1
,
2
]
reduce的使用
與map一樣,reduce(function, iterable)也接收兩個參數,第一個參數代表的是接收一個函數,第二個參數代表的是接收一個iteralbe類型的對象,比如list。不過不同的地方在於reduce中的這個
函數必須要接收兩個參數
,下面我們來通過求一個list(列表)累加和的例子
來了解一下reduce的用法。
from
functools
import
reduce
# 使用lambda定義一個函數,函數的作用是接收兩個參數,然後返回兩個參數之和
>>>
function
=
lambda
x
,
y
:
x
+
y
>>>
iterable
=
[
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
]
# 函數function每次接收兩個參數,除第一次外每次從iterable中取一個元素作為一個參數
# 另外一個參數取自上一次function返回的值
>>>
reduce
(
function
,
iterable
)
45
filter的使用
和map/reduce類似,filter(function, iterable)一次也接收兩個參數,一個參數是函數,另外一個參數是iterable對象,從名字也可以看出,filter用於過濾iterble對象,比如說list(列表)。
它的原理是每次從iterable對象中取出一個元素作用於我們的function,如果function返回True就保留該元素,如果返回False就刪除該元素。下面我們通過一個實例來看一下filter的用法。
# 定義一個函數,如果接收的字元s為空,那麼返回False,如果為非空,那麼返回True
>>>
function
=
lambda
s
:
s
and
s
.
strip
()
>>>
iterable
=
[
"AJ"
,
" "
,
"Stussy"
,
""
,
"CLOT"
,
"FCB"
,
None
]
>>>
filter
(
function
,
iterable
)
<
filter
at
0x7fcb562319b0
>
>>>
list
(
filter
(
function
,
iterable
))
[
"AJ"
,
"Stussy"
,
"CLOT"
,
"FCB"
]
裝飾器
裝飾器(decorator)是一種高級Python語法。裝飾器可以對一個函數、方法或者類進行加工。合理地使用裝飾器可以減少我們的代碼量以及提高程序的可讀型,在很多Python框架中,比如Django中我們可以大量看到裝飾器的身影。
>>>
def
add
(
x
,
y
)
:
...
return
x
+
y
...
>>>
def
multiply
(
x
,
y
)
:
...
return
x
*
y
...
現在我們有上面兩個函數,分別用來求加法和乘法,但是現在我們覺得功能不夠,想在返回結果前添加一些輸出語句,一般來說我們要重構兩個函數,就向下面這樣。
>>>
def
add
(
x
,
y
)
:
...
(
"input:"
,
x
,
y
)
...
return
x
+
y
...
>>>
def
multiply
(
x
,
y
)
:
...
(
"input:"
,
x
,
y
)
...
return
x
*
y
...
如果使用裝飾器我們可以像下面這樣做,雖然現在我們這種情形看起來使用裝飾器並沒有什麼優勢,但是如果我們要添加的不止一條列印功能,以及除了add/multiply我們還有minus/divide等函數,這個時候裝飾器的威力就體現出來了,我們只用修改一處代碼即可,這樣不僅提高了程序的可讀性而且也為以後我們重構代碼省去了很多的工作量。
def
decorator
(
F
)
:
def
new_function
(
x
,
y
)
:
(
"input:"
,
x
,
y
)
return
F
(
x
,
y
)
return
new
_
function@
decorator
def
add
(
x
,
y
)
:
return
x
+
y
@
decorator
def
multiply
(
x
,
y
)
:
return
x
*
y
來源:ZiWenXie
ziwenxie.site/2016/12/11/python-function-programming/
Python開發整理髮布,轉載請聯繫作者獲得授權
【點擊成為Java大神】


TAG:Python開發 |