天天看點

《python 與資料挖掘 》一第3章 函  數建立了一個以3為底的匿名對數函數,并指派給了My_LF使用My_LF調用匿名函數,參數隻需要真數即可,底數已設定為3。而使用log()函數需要同時指定真數和對數。如果我們每次都是求以3為底數的對數,使用My_LF更友善。result: 2.0

本章将介紹如何使用python編寫函數。函數是python為了代碼效率的最大化,減少備援而提供的最基本的程式結構。在上一章中,我們學會了衆多流程控制的語句,在中大型的程式中,同一段代碼可能會被使用多次,如果程式由一段又一段備援的流程控制語句組成,那麼程式的可讀性會變差。是以,我們需要使用函數去封裝這些重複使用的程式段,并加以注釋,下次使用的時候就可以直接調用,使代碼更清晰明白。

本書在這裡第一次講到函數封裝的概念,實際上我們在前面已經接觸到了。例如清單操作的各種方法都是函數,在執行list.append(x)的時候在底層程式已經執行了一段代碼。如果不封裝成函數,每次添加元素都要輸入這段代碼,顯得非常繁瑣。程式員沒有必要去探究資料結構源碼具體是如何編寫的,每種資料結構都會提供衆多的函數和相對應的說明文檔,程式員僅需知道函數的輸入和輸出就可以使用資料結構去工作了。

函數能使程式變得抽象。抽象節省了工作,并且加大了程式的可讀性。例如,寫一個求一列資料的極差的程式,我們可以分解成如下工作:

1)求最大值。

2)求最小值。

3)求極差,極差=最大值-<code>`</code>javascript

def fun():

print 'hello,world'

這樣就定義了一個fun函數,它沒有參數,也沒有傳回值,僅僅列印出“hello,world”。下面再定義一個有參數也有傳回值的函數。

這個函數稱為hello,輸入參數是your_name,傳回加上hello的字元串。程式建立函數後,執行 s = hello('tom')即得到一個新的字元串“hello tom”并指派給s。python的簡潔性可以從函數中展現,python的參數也不需要聲明資料類型,但這也有一定的弊端,程式員可能會因不清楚參數的資料類型而輸入錯誤的參數,例如上面的函數若執行hello(1)就會報錯。是以一般在函數的開頭注明函數的用途、輸入和輸出。

return語句用于傳回一個結果對象。python可以沒有傳回值,可以有一個傳回值,也可以有多個傳回值,傳回值的資料類型沒有限制。當程式執行到函數中的return語句時,就會将指定的值傳回并結束函數,如果return後面還有語句,那些語句将不會被執行。是以也可以僅僅用一個return結束函數。在其他語言中很少允許多個傳回值,舉一個python有多個傳回值函數的例子:

lambda語句

python允許使用lambda語句建立匿名函數,也就是說函數沒有具體的名稱。可能讀者會産生疑惑,函數沒有了名稱應該不會是一件好事。但實際上,使用python編寫一些執行腳本時,使用lambda省去了定義函數的過程,代碼變得精簡。對于一些抽象的、不會在其他地方複用的函數,有時候給函數命名也是個難題(需要避免函數重名),而使用lambda則不需要考慮函數命名的問題。

lamber語句中,冒号前是函數參數,若有多個函數使用逗号分隔,冒号右邊是傳回值。如此便建構了一個函數對象,def語句也是建立一個函數對象,隻是lambda建立的函數對象沒有名字。

2

使用lamber函數應該注意下面4點:

1)lambda定義的是單行函數,如果需要複雜的函數,應使用def語句。

2)lamdda參數清單可以包含多個函數,如lambda x,y : x + y 。

3)lambda語句有且隻有一個傳回值。

4)lambda語句中的表達式不能含有指令,而且僅限一條表達式。

舉一個例子,python的數學庫中隻有以自然底數e和10為底的對數函數,下面我們使用lambda函數建立指定某個數為底的對數函數,如代碼清單<code>`</code>javascript3-1所示。

代碼清單3-1 匿名函數

my_lf = make_logarithmic_function(3)

print my_lf(9)

*代碼詳見:示例程式/code/3-1.py

繼續閱讀