A. 為什麼要用函數式編程
以 C 語言源程序為例,使用函數式的編程風格主要是有利於程序的調試!而且程序的可讀性也很好。程序思路很清楚!!以下面的源程序進行講解就一目瞭然了。在以下題目中,三次用到了求階乘的代碼(A!、(A-B)!、B!),現在使用調用子函數的編程風格,程序簡潔明了、且可讀性很強。如果不使用函數式編程,那麼求階乘的代碼你就必須要重復三次。你說到底是哪一種編程風格好呢?
例如:求組合數C(A,B) = A!/( (A-B)! * B! )
int jie_cheng( int ) ;
void main( )
{
int a = 0,b = 0 , c = 0 ;
scanf("%d %d",&a,&b);
c = jie_cheng(a) / (jie_cheng(a-b)*jiecheng(b)) ;
printf("Zu he shu C is: %d\n", c);
}
int jie_cheng(int num)
{
if( num == 1)
return 1 ;
else
return num*jie_cheng(num-1) ;
}
B. 函數式編程的特點
函數式編程具有五個鮮明的特點。
1、函數是"第一等公民"
所謂"第一等公民"(first class),指的是函數與其他數據類型一樣,處於平等地位,可以賦值給其他變數,也可以作為參數,傳入另一個函數,或者作為別的函數的返回值。
2、只用"表達式",不用"語句"
"表達式"(expression)是一個單純的運算過程,總是有返回值;"語句"(statement)是執行某種操作,沒有返回值。函數式編程要求,只使用表達式,不使用語句。也就是說,每一步都是單純的運算,而且都有返回值。
3、沒有"副作用"
所謂"副作用"(side effect),指的是函數內部與外部互動(最典型的情況,就是修改全局變數的值),產生運算以外的其他結果。
4、不修改狀態
上一點已經提到,函數式編程只是返回新的值,不修改系統變數。因此,不修改變數,也是它的一個重要特點。
5、引用透明性
函數程序通常還加強引用透明性,即如果提供同樣的輸入,那麼函數總是返回同樣的結果。就是說,表達式的值不依賴於可以改變值的全局狀態。
C. 畢業生必看Python函數式編程
學Python都應該了解的函數式編程
Python函數式編程
函數式編程(Functional
Programming) 或者函數程序設計, 是
一種編程范型。
它將計算機運算視為數學上的函數運算,
並且避免使用程序狀態以及變數對象。
以上只是簡單的函數式編程的概念,我們
只需簡單了解即可。
在Python中, 函數式編程主要由幾個函
數的使用構成:lambda() , map() ,
rece() , filter() 等。
1.lambda函數
lambda函數, 又成為匿名函數。
lambda函數只能有一個表達式, 而不需
要寫return來返回函數的值。當然, 匿
名函數也是一個函數對象,同樣可以把匿
名函數賦值給一個變數。
也可以把匿名函數作為返回值來返回
可以看出, 變數f就是一個lambda函數
類型,需要使用f()來調用該函數。
2.map函數
map函數接收兩個參數, 一個是函數,
個是Inter able(可迭代序列) , map
函數依次將函數作用到序列的每個元素,
並把結果作為新的Inter able返回。
看一個例子:如圖
一個簡單的列表解析,把列表a的每個元
素都加2, 用map函數可以寫為:如圖
由於map函數返回的是一個惰性序列,
需要通過list() 等函數來調用它。
雖然上面的代碼看起來比直接寫for循環
要復雜,但是當數據量很大的情況下,
Python的for效率就不是很高了, 而
map的效率是可以接近C語言的。同時
代碼也簡潔很多,簡直裝X神器。
3.rece函數
它和map有些像, 不過map是用於逐
一遍歷, 而rece函數是用來遞歸計算
的。
一個簡單的序列求和
對列表a的各個元素依次求和,再看一個
自製的int() 函數的例子
這是Python內置函數int的用法
4.filter函數
它同樣接收一個函數和一個序列,
filter() 把傳入的函數依次作用於每個元
素, 然後根據返回值是True還是False
決定保留還是丟棄該元素。
使用這些函數,不僅可以讓我們的代碼更加簡潔,
同時在大數據量或者計算密集時,能夠大大提高效率。