這大概算是Python最難啃的一塊骨頭吧。在我 Python生涯的這一年裏,我遇到了一些Pythoner,他們毫無例外地徹底不會使用函數式編程(有些人喜歡稱爲Pythonic),好比,歷來不會 傳遞函數,不知道lambda是什麼意思,知道列表展開但歷來不知道用在哪裏,對Python不提供經典for循環感到無所適從,言談之中表現出對函數式 風格的一種抗拒甚至厭惡。 html
我嘗試剖析這個問題,最終總結了這麼兩個緣由:一、不想改變,認爲現有的知識能夠完成任務;二、對小衆語言的歧視,Python目前在國內市場份額仍然很小很小,熟悉Python風格用處不大。 算法
然而我認爲,學習使用一種大相徑庭的風格能夠顛覆整個編程的思想。我會慢慢總結一個系列共4篇文字,篇幅都不大,輕鬆就能看完,但願對喜歡Python的人們有所幫助,由於我我的確實從中受益不淺。 編程
仍是那句老話,尊重做者的勞動,轉載請註明原做者和原地址:)數據結構
函數式編程使用一系列的函數解決問題。函數僅接受輸入併產生輸出,不包含任何能影響產生輸出的內部狀態。任何狀況下,使用相同的參數調用函數始終能產生一樣的結果。 閉包
在 一個函數式的程序中,輸入的數據「流過」一系列的函數,每個函數根據它的輸入產生輸出。函數式風格避免編寫有「邊界效應」(side effects)的函數:修改內部狀態,或者是其餘沒法反應在輸出上的變化。徹底沒有邊界效應的函數被稱爲「純函數式的」(purely functional)。避免邊界效應意味着不使用在程序運行時可變的數據結構,輸出只依賴於輸入。 app
能夠認爲函數式編程恰好站在了面 向對象編程的對立面。對象一般包含內部狀態(字段),和許多能修改這些狀態的函數,程序則由不斷修改狀態構成;函數式編程則極力避免狀態改動,並經過在函 數間傳遞數據流進行工做。但這並非說沒法同時使用函數式編程和麪向對象編程,事實上,複雜的系統通常會採用面向對象技術建模,但混合使用函數式風格還能 讓你額外享受函數式風格的優勢。 編程語言
函數式的風格一般被認爲有以下優勢: ide
支持函數式編程的語言一般具備以下特徵,大量使用這些特徵的代碼便可被認爲是函數式的: 模塊化
1
2
3
4
5
6
7
8
9
|
#僞代碼
interface Comparator {
compare(o1, o2)
}
lst
=
list
(
range
(
5
))
lst.sort(Comparator() {
compare(o1, o2) {
return
o2
-
o1
/
/
逆序
})
|
1
2
3
4
|
def
compare(o1, o2):
return
o2
-
o1
#逆序
lst
=
list
(
range
(
5
))
lst.sort(compare)
|
1
|
lst.sort(
lambda
o1, o2: o1.compareTo(o2))
|
1
2
3
4
|
lst2
=
list
()
for
i
in
range
(
len
(lst)):
#模擬經典for循環
if
lst[i] >
0
:
lst2.append(lst[i])
|
1
|
lst2
=
filter
(
lambda
n: n >
0
, lst)
|
1
2
3
4
5
6
7
8
9
|
class
greater_than_helper:
def
__init__(
self
, minval):
self
.minval
=
minval
def
is_greater_than(
self
, val):
return
val >
self
.minval
def
my_filter(lst, minval):
helper
=
greater_than_helper(minval)
return
filter
(helper.is_greater_than, lst)
|
1
2
|
def
my_filter(lst, minval):
return
filter
(
lambda
n: n > minval, lst)
|