1. 程式人生 > >第四天 PYTHON 函數

第四天 PYTHON 函數

特點 可能 res peer ner 應該 集合 返回 需求

本節內容

1. 函數基本語法及特性

2. 參數與局部變量

3. 返回值

嵌套函數

4.遞歸

5.匿名函數

6.函數式編程介紹

7.高階函數

8.內置函數

函數與函數式編程

1、面向對象: 華山派---->類----> class
2、面向過程: 少林派---->過程---->def
3、函數式編程:逍遙派---->函數---->def

函數與函數式編程


1.介紹:

在過去的十年間,大家廣為熟知的編程方法無非兩種:面向對象和面向過程,其實,無論哪種,都是一種編程的規範或者是如何編程的方法論。而如今,一種更為古老的編程方式:函數式編程,以其不保存狀態,不修改變量等特性重新進入人們的視野。下面我們就來依次了解這一傳統的編程理念,讓我們從基本的函數概念開始。


2.函數定義:

初中數學函數定義:一般的,在一個變化過程中,如果有兩個變量x和y,並且對於x的每一個確定的值,y都有唯一確定的值與其對應,那麽我們就把x稱為自變量,把y稱為因變量,y是x的函數。自變量x的取值範圍叫做這個函數的定義域,編程語言中函數定義:函數是邏輯結構化和過程化的一種編程方法。

函數定義規範

def:定義函數的關鍵字
test:函數名
():內可定義形參
"":文檔描述(非必要,但是強烈建議為你的函數添加描述信息)
x+=1:泛指代碼塊或程序處理邏輯
return:定義返回值

補充:
函數式編程就是:先定義一個數學函數,然後按照這個數學模型用編程語言去實現它。至於具體如何實現和這麽做的好處,後續我會詳細介紹。

ps:

python中函數定義方法:

技術分享圖片
 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-      
 3 #Author: nulige
 4 
 5 #函數
 6 def func1():
 7     ‘‘‘testing‘‘‘
 8     print(‘in the func1‘)
 9     return 0
10 
11 #過程
12 def func2():
13     ‘‘‘testing‘‘‘
14     print(‘in the func2‘)
15 
16 x=func1()
17 y=func2()
18 
19 print(‘from func1 return is %s‘ %x)
20 print(‘from func2 return is %s‘ %y)
技術分享圖片

執行結果:

1 in the func1
2 in the func2
3 from func1 return is 0
4 from func2 return is None

3.為何使用函數:

沒有函數的編程只是在寫邏輯(功能),想脫離函數,重用你的邏輯,唯一的方法就是拷貝

例一:

假設我們編寫好了一個邏輯(功能),用來以追加的方式寫日誌:

技術分享圖片
 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-      
 3 #Author: nulige
 4 
 5 #假設我們編寫好了一個邏輯(功能),用來以追加的方式寫日誌:
 6 with open(‘a.txt‘,‘a+‘) as f:
 7       f.write(‘end action‘)
 8 
 9 
10 #現在有三個函數,每個函數在處理完自己的邏輯後,都需要使用上面這個邏輯,那麽唯一的方法就是,拷貝三次這段邏輯
11 def test1():
12     print(‘in the test1‘)
13 with open(‘a.txt‘,‘a+‘) as f:
14       f.write(‘end action‘)
15 
16 def test2():
17     print(‘in the test2‘)
18 with open(‘a.txt‘,‘a+‘) as f:
19       f.write(‘end action‘)
20 
21 def test3():
22     print(‘in the test3‘)
23 with open(‘a.txt‘,‘a+‘) as f:
24       f.write(‘end action‘)
25 
26 test1()
27 test2()
28 test3()
29 
30 #那麽假設有>N個函數都需要使用這段邏輯,你可以拷貝N次嗎?
技術分享圖片

執行結果:

1 in the test1
2 in the test2
3 in the test3

接著會生成一個a.txt的文件,裏面內容如下:

1 end action
2 end action
3 end action

例二:

優化後的代碼,用函數的方法來實現

技術分享圖片
 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-      
 3 #Author: nulige
 4 
 5 #假設我們編寫好了一個邏輯(功能),用來以追加的方式寫日誌:
 6 
 7 #下面用函數的方法來實現
 8 def logger():
 9     with open(‘a.txt‘,‘a+‘) as f:
10         f.write(‘end action\n‘)
11 
12 def test1():
13     print(‘in the test1‘)
14 
15     logger()
16 def test2():
17     print(‘in the test2‘)
18 
19     logger()
20 
21 def test3():
22     print(‘in the test3‘)
23 
24     logger()
25 
26 test1()
27 test2()
28 test3()
技術分享圖片

執行結果:

1 in the test1
2 in the test2
3 in the test3

接著會生成一個a.txt的文件,裏面內容如下:

1 end action
2 end action
3 end action

例三:

需求變了(讓我們來為日誌加上時間吧)

技術分享圖片
 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-      
 3 #Author: nulige
 4 
 5 #假設我們編寫好了一個邏輯(功能),用來以追加的方式寫日誌:
 6 #下面用函數的方法來實現
 7 
 8 import time
 9 def logger():
10     time_format=‘%Y-%m-%d %X‘
11     time_current=time.strftime(time_format)
12     with open(‘a.txt‘,‘a+‘) as f:
13         f.write(‘%s end action\n‘ %time_current)
14 
15 def test1():
16     print(‘in the test1‘)
17 
18     logger()
19 def test2():
20     print(‘in the test2‘)
21 
22     logger()
23 
24 def test3():
25     print(‘in the test3‘)
26 
27     logger()
28 
29 test1()
30 test2()
31 test3()
技術分享圖片

執行結果:

1 in the test1
2 in the test2
3 in the test3

接著會生成一個a.txt的文件,裏面內容如下:

1 2016-11-15 15:55:56 end action
2 2016-11-15 15:55:56 end action
3 2016-11-15 15:55:56 end action

總結例二和例三可概括使用函數的三大優點

1.代碼重用

2.保持一致性

3.可擴展性

4.函數和過程:

過程定義:過程就是簡單特殊沒有返回值的函數

這麽看來我們在討論為何使用函數的的時候引入的函數,都沒有返回值,沒有返回值就是過程,沒錯,但是在python中有比較神奇的事情

技術分享圖片
 1 def test01():
 2     msg=‘hello The little green frog‘
 3     print msg
 4  
 5 def test02():
 6     msg=‘hello WuDaLang‘
 7     print msg
 8     return msg
 9  
10  
11 t1=test01()
12  
13 t2=test02()
14  
15  
16 print ‘from test01 return is [%s]‘ %t1
17 print ‘from test02 return is [%s]‘ %t2
技術分享圖片

總結:當一個函數/過程沒有使用return顯示的定義返回值時,python解釋器會隱式的返回None,

所以在python中即便是過程也可以算作函數。

5.函數返回值:

ps1:

技術分享圖片
1 def test1():
2     print(‘in the test1‘)
3     return 0
4     print(‘test end‘)
5 
6 test1()
技術分享圖片

執行結果:

1 in the test1

ps2:

技術分享圖片
 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-      
 3 #Author: nulige
 4 
 5 def test1():
 6     print(‘in the test1‘)
 7     return 0
 8 
 9 x=test1()
10 print(x)
技術分享圖片

執行結果:

1 0

ps3:

技術分享圖片
 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-      
 3 #Author: nulige
 4 
 5 def test1():
 6     print(‘in the test1‘)
 7 
 8 def test2():
 9     print(‘in the test2‘)
10     return 0
11 
12 def test3():
13     print(‘in the test3‘)
14     return 1,‘hello‘,[‘alex‘,‘wupeiqi‘],{‘name‘:‘alex‘}
15 
16 x=test1()
17 y=test2()
18 z=test3()
19 print(x)
20 print(y)
21 print(z)
技術分享圖片

執行結果:

技術分享圖片
1 in the test1
2 in the test2
3 in the test3
4 None
5 0
6 (1, ‘hello‘, [‘alex‘, ‘wupeiqi‘], {‘name‘: ‘alex‘})
技術分享圖片

總結:

返回值數=0:返回None

返回值數=1:返回object

返回值數>1:返回tuple (元組)

ps4:

技術分享圖片
 1 def test01():
 2     pass
 3  
 4 def test02():
 5     return 0
 6  
 7 def test03():
 8     return 0,10,‘hello‘,[‘alex‘,‘lb‘],{‘WuDaLang‘:‘lb‘}
 9  
10 t1=test01()
11 t2=test02()
12 t3=test03()
13  
14  
15 print ‘from test01 return is [%s]: ‘ %type(t1),t1
16 print ‘from test02 return is [%s]: ‘ %type(t2),t2
17 print ‘from test03 return is [%s]: ‘ %type(t3),t3
技術分享圖片

總結:

返回值數=0:返回None

返回值數=1:返回object

返回值數>1:返回tuple

說明一下return可以返回任何參數?

答案是可以的

ps:

技術分享圖片
 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-      
 3 #Author: nulige
 4 
 5 def test1():
 6     print(‘in the test1‘)
 7 
 8 def test2():
 9     print(‘in the test2‘)
10     return 0
11 
12 def test3():
13     print(‘in the test3‘)
14    # return 1,‘hello‘,[‘alex‘,‘wupeiqi‘],{‘name‘:‘alex‘}
15     return test2     #可以return任何值,返回的是內存地址
16 
17 x=test1()
18 y=test2()
19 z=test3()
20 print(x)
21 print(y)
22 print(z)
技術分享圖片

執行結果:

技術分享圖片
1 in the test1
2 in the test2
3 in the test3
4 None
5 0
6 <function test2 at 0x01C34C90>    #返回的是內存地址
技術分享圖片

6.函數調用:

調用方法:

1.test()執行,()表示調用函數test,()內可以有參數也可沒有

參數:

1.形參和實參

技術分享圖片

形參:形式參數,不是實際存在,是虛擬變量。在定義函數和函數體的時候使用形參,目的是在函數調用時接收實參(記住:實參個數,類型應與實參必須一一對應,不能超,否則會報錯)

實參:實際參數,調用函數時傳給函數的參數,可以是常量,變量,表達式,函數,傳給形參

區別:形參是虛擬的,不占用內存空間,.形參變量只有在被調用時才分配內存單元,實參是一個變量,占用內存空間,數據傳送單向,實參傳給形參,不能形參傳給實參

形參和實參示例

技術分享圖片
1 #!/usr/bin/env python
2 # -*- coding:utf-8 -*-      
3 #Author: nulige
4 
5 def test(x,y):
6     print(x)
7     print(y)
8 
9 test(1,2)
技術分享圖片

執行結果:

1 1
2 2

實參和形參必須一一對應,不能超否則會報錯。

技術分享圖片
1 #!/usr/bin/env python
2 # -*- coding:utf-8 -*-      
3 #Author: nulige
4 
5 def test(x,y):
6     print(x)
7     print(y)
8 
9 test(2,1,3)
技術分享圖片

執行結果:

1 Traceback (most recent call last):
2   File "D:/python/day4/func_test5.py", line 9, in <module>
3     test(2,1,3)
4 TypeError: test() takes 2 positional arguments but 3 were given

2.位置參數和關鍵字(標準調用:實參與形參位置一一對應;關鍵字調用:位置無需固定)

ps1:

技術分享圖片
1 #!/usr/bin/env python
2 # -*- coding:utf-8 -*-      
3 #Author: nulige
4 
5 def test(x,y):
6     print(x)
7     print(y)
8 
9 test(y=2,x=1)
技術分享圖片

執行結果:

1 1
2 2

ps2:

技術分享圖片
 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-      
 3 #Author: nulige
 4 
 5 def test(x,y,z):
 6     print(x)
 7     print(y)
 8     print(z)
 9 
10 #test(y=2,x=1)   #與形參順序無關
11 #test(1,2)       #與形參一一對應
12 
13 #test(x=2,3)   #錯誤用法,會報錯
14 #test(3,x=2)   #錯誤用法,會報錯,先給了x一個3,又給了一個2,y就變得沒有值了,所以報錯了。
15 #test(3,y=2)
16 
17 #即有關鍵字調用,又有位置參數調用,按照位置參數的來。
18 #test(3,y=2,6)   #註意:關鍵參數,不能寫在位置參數前面。
19 
20 test(3,6,z=2)
技術分享圖片

執行結果:

1 3
2 6
3 2

3.默認參數

ps1:

技術分享圖片
 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-      
 3 #Author: nulige
 4 
 5 def test(x,y=2):
 6 
 7     print(x)
 8     print(y)
 9 
10 test(1,y=3)
11 
12 #默認參數特點:調用函數的時候,默認參數非必須傳遞
技術分享圖片

執行結果:

1 1
2 3

ps2:

技術分享圖片
 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-      
 3 #Author: nulige
 4 
 5 def test(x,soft1=True,soft2=True):
 6     print(x)
 7 test(1,3)
 8 
 9 #默認參數特點:調用函數的時候,默認參數非必須傳遞
10 #用途:1、默認安裝值
技術分享圖片

執行結果:

1 1 

ps3:

連接mysql數據庫,設置固定值

技術分享圖片
1 #!/usr/bin/env python
2 # -*- coding:utf-8 -*-      
3 #Author: nulige
4 
5 def conn(host,prot=3306):
6     pass
7 
8 conn()
技術分享圖片

4.參數組

ps1:

傳值的時候,不能多,可以少,最少不能少於print的值(這裏是2個),否則會報錯

技術分享圖片
 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-      
 3 #Author: nulige
 4 
 5 def test(x,y,z=2):
 6     print(x)
 7     print(y)
 8 
 9 test(1,2)
10 #test(1,2,3)   #傳值的時候,不能多,可以少,最少不能少於print的值(這裏是2個),否則會報錯
技術分享圖片

執行結果:

1 1
2 2

ps2:

多個實參,放到一個元組裏面,以*開頭,可以傳多個參數

技術分享圖片
 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-      
 3 #Author: nulige
 4 
 5 #多個實參,放到一個元組裏面,以*開頭,可以傳多個參數
 6 #*代表接受的參數不固定
 7 def test(*args):
 8     print(args)
 9 
10 test(1,2,3,4,5,6)
11 test(*[1,2,4,5,6])    #args=tuple([1,2,3,4,5,6])
技術分享圖片

執行結果:

1 (1, 2, 3, 4, 5, 6)
2 (1, 2, 4, 5, 6)

ps3:

技術分享圖片
 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-      
 3 #Author: nulige
 4 
 5 #位置參數傳值的時候不參超
 6 def test1(x,*args):
 7     print(x)
 8     print(args)
 9 
10 test1(1,2,3,4,5,6,7)
技術分享圖片

執行結果:

1 1
2 (2, 3, 4, 5, 6, 7)

ps4:

技術分享圖片
1 #!/usr/bin/env python
2 # -*- coding:utf-8 -*-      
3 #Author: nulige
4 
5 # **kwargs把N個關鍵字參數,轉換為字典的方式
6 def test2(**kwargs):
7     print(kwargs)
8 
9 test2(name=‘alex‘,age=8,sex=‘F‘)
技術分享圖片

執行結果:

1 {‘sex‘: ‘F‘, ‘name‘: ‘alex‘, ‘age‘: 8}

ps5:

技術分享圖片
 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-      
 3 #Author: nulige
 4 
 5 # **kwargs把N個關鍵字參數,轉換為字典的方式
 6 def test2(**kwargs):
 7     print(kwargs)
 8     print(kwargs[‘name‘])
 9     print(kwargs[‘age‘])
10     print(kwargs[‘sex‘])
11 
12 test2(name=‘alex‘,age=8,sex=‘F‘)
技術分享圖片

執行結果:

1 {‘age‘: 8, ‘sex‘: ‘F‘, ‘name‘: ‘alex‘}
2 alex
3 8
4 F

ps6:

技術分享圖片
 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-      
 3 #Author: nulige
 4 
 5 def test4(name,age=18,**kwargs):
 6     print(name)
 7     print(age)
 8     print(kwargs)
 9 
10 test4(‘alex‘,age=34,sex=‘m‘,hobby=‘tesla‘)
技術分享圖片

執行結果:

1 alex
2 34
3 {‘hobby‘: ‘tesla‘, ‘sex‘: ‘m‘}

ps7:

非固定參數

若你的函數在定義時不確定用戶想傳入多少個參數,就可以使用非固定參數

技術分享圖片
 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-      
 3 #Author: nulige
 4 
 5 def test4(name,age=18,**kwargs):
 6     print(name)
 7     print(age)
 8     print(kwargs)
 9 
10 test4(‘alex‘,age=34,sex=‘m‘,hobby=‘tesla‘)
技術分享圖片

執行結果:

1 alex     #傳給name
2 34       #age=34 傳給age=18,並覆蓋他的內容
3 {‘hobby‘: ‘tesla‘, ‘sex‘: ‘m‘}     # 傳給字典 sex=‘m‘,hobby=‘tesla‘

ps8:

用函數調用的方法

技術分享圖片
 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-      
 3 #Author: nulige
 4 
 5 def test4(name,age=18,**kwargs):
 6     print(name)
 7     print(age)
 8     print(kwargs)
 9 
10 def logger(source):    #用函數調用的方法
11     print("from %s" % source)
12     
13 test4(‘alex‘,age=34,sex=‘m‘,hobby=‘tesla‘)
技術分享圖片

執行結果:

1 alex
2 34
3 {‘hobby‘: ‘tesla‘, ‘sex‘: ‘m‘}


全局與局部變量

在子程序中定義的變量稱為局部變量,在程序的一開始定義的變量稱為全局變量。 全局變量作用域是整個程序,局部變量作用域是定義該變量的子程序。 當全局變量與局部變量同名時: 在定義局部變量的子程序內,局部變量起作用;在其它地方全局變量起作用。

局部變量

ps1:

技術分享圖片
 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-      
 3 #Author: nulige
 4 
 5 def change_name(name):
 6     print("before change",name)
 7     name="Alex li"   #這個函數就是這個變量的作用域(只在局部生效)
 8     print(‘after change‘,name)
 9 
10 name = "alex"
11 change_name(name)
12 print(name)
技術分享圖片

執行結果:

1 before change alex
2 after change Alex li
3 alex

全局變量

ps1:

技術分享圖片
 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-      
 3 #Author: nulige
 4 
 5 school = "Oldboy edu."   #全局變量
 6 
 7 def change_name(name):
 8     global school          #聲明(必須先聲明,才能把Oldboy改成Mage Linux。大家忘記這種方法吧! 記住這句話:不應該在函數裏面改全局變量)
 9     school = "Mage Linux"
10     print("before change",name,school)
11     name="Alex li"   #這個函數就是這個變量的作用域(只在局部生效)
12     age =23
13     print("after change",name)
14 
15 name = "alex"
16 change_name(name)
17 print(name)
18 print("school:",school)
技術分享圖片

執行結果:

1 before change alex Mage Linux
2 after change Alex li
3 alex
4 school: Mage Linux     #聲明後就把Oldboy 改成了Mage Linux

ps2:

#註意事項:只有字符串和單獨的整數,不能在函數裏面改。其它列表,字典,集合、類都可以在局部變量裏面更改的。

技術分享圖片
 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-      
 3 #Author: nulige
 4 
 5 school = "Oldboy edu."
 6 names = ["Alex","Jack","Rain"]
 7 def change_name():
 8 
 9     names[0] = "金角大王"
10     print("inside func",names)
11 
12 change_name()
13 print(names)
14 
15 #註意事項:只有字符串和單獨的整數,不能在函數裏面改。其它列表,字典,集合、類都可以在局部變量裏面更改的。
技術分享圖片

執行結果:

1 inside func [‘金角大王‘, ‘Jack‘, ‘Rain‘]
2 [‘金角大王‘, ‘Jack‘, ‘Rain‘]


遞歸

在函數內部,可以調用其他函數。如果一個函數在內部調用自身本身,這個函數就是遞歸函數。

ps1:

技術分享圖片
1 def calc(n):
2     print(n)
3     if int(n/2) ==0:
4         return n
5     return calc(int(n/2))
6  
7 calc(10)
技術分享圖片

執行結果:

1 10
2 5
3 2
4 1

ps2:

技術分享圖片
1 #!/usr/bin/env python
2 # -*- coding:utf-8 -*-      
3 #Author: nulige
4 
5 def calc(n):
6     print(n)
7     return calc(n+1)
8 calc(0)    #最大遞歸999層
技術分享圖片

執行結果:

技術分享圖片
1 0
2 1
3 2
4 3
5 ......  中間省略
6 999
7 
8 RecursionError: maximum recursion depth exceeded while calling a Python object
技術分享圖片

ps3:

技術分享圖片
 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 #Author: nulige
 4 
 5 def calc(n):
 6     print(n)
 7     if int(n/2) >0:
 8         return calc(int(n/2))
 9     print("->",n)
10 
11 calc(10)
技術分享圖片

執行結果:

1 10000000000

ps4:

階乘 n! = n * (n-1) * (n-2) * ... * 2 * 1

  • 階乘擁有相同的子模式 n * (n-1)

  • 隨著運算的進行,乘數越來越少(問題規模遞減)

  • 當n=1時,運算結束(結束條件n=1)

  • 如計算5!,則種子值為5

技術分享圖片
1 def factorial(n):
2      print(n)
3     if n == 1:
4         return n
5     else:
6         ret = n * factorial(n-1)
7         print(ret)
8         return ret
技術分享圖片

執行結果:

技術分享圖片
 1 5
 2 4
 3 3
 4 2
 5 1
 6 2
 7 6
 8 24
 9 120
10 120
技術分享圖片

遞歸特性:

1. 必須有一個明確的結束條件

2. 每次進入更深一層遞歸時,問題規模相比上次遞歸都應有所減少

3. 遞歸效率不高,遞歸層次過多會導致棧溢出(在計算機中,函數調用是通過棧(stack)這種數據結構實現的,每當進入一個函數調用,棧就會加一層棧幀,每當函數返回,棧就會減一層棧幀。由於棧的大小不是無限的,所以,遞歸調用的次數過多,會導致棧溢出)

堆棧掃盲http://www.cnblogs.com/lln7777/archive/2012/03/14/2396164.html

遞歸函數實際應用案例,二分查找

技術分享圖片
 1 data = [1, 3, 6, 7, 9, 12, 14, 16, 17, 18, 20, 21, 22, 23, 30, 32, 33, 35]
 2  
 3  
 4 def binary_search(dataset,find_num):
 5     print(dataset)
 6  
 7     if len(dataset) >1:
 8         mid = int(len(dataset)/2)
 9         if dataset[mid] == find_num:  #find it
10             print("找到數字",dataset[mid])
11         elif dataset[mid] > find_num :# 找的數在mid左面
12             print("\033[31;1m找的數在mid[%s]左面\033[0m" % dataset[mid])
13             return binary_search(dataset[0:mid], find_num)
14         else:# 找的數在mid右面
15             print("\033[32;1m找的數在mid[%s]右面\033[0m" % dataset[mid])
16             return binary_search(dataset[mid+1:],find_num)
17     else:
18         if dataset[0] == find_num:  #find it
19             print("找到數字啦",dataset[0])
20         else:
21             print("沒的分了,要找的數字[%s]不在列表裏" % find_num)
22  
23  
24 binary_search(data,66)
技術分享圖片

匿名函數

匿名函數就是不需要顯式的指定函數

技術分享圖片
1 #這段代碼
2 def calc(n):
3     return n**n
4 print(calc(10))
5  
6 #換成匿名函數
7 calc = lambda n:n**n
8 print(calc(10))
技術分享圖片

你也許會說,用上這個東西沒感覺有毛方便呀, 。。。。呵呵,如果是這麽用,確實沒毛線改進,不過匿名函數主要是和其它函數搭配使用的呢,如下

1 res = map(lambda x:x**2,[1,5,7,4,8])
2 for i in res:
3     print(i)

輸出

技術分享圖片
1 1
2 25
3 49
4 16
5 64
6 
7  
技術分享圖片

函數式編程介紹 

函數是Python內建支持的一種封裝,我們通過把大段代碼拆成函數,通過一層一層的函數調用,就可以把復雜任務分解成簡單的任務,這種分解可以稱之為面向過程的程序設計。函數就是面向過程的程序設計的基本單元。

函數式編程中的函數這個術語不是指計算機中的函數(實際上是Subroutine),而是指數學中的函數,即自變量的映射。也就是說一個函數的值僅決定於函數參數的值,不依賴其他狀態。比如sqrt(x)函數計算x的平方根,只要x不變,不論什麽時候調用,調用幾次,值都是不變的。

ps:

技術分享圖片
 1 y=2+4
 2 
 3 y=f(2,4)
 4 
 5         6
 6 
 7 y=f(2,6)
 8 
 9         if  x+y>7
10 
11                 return 0
技術分享圖片

Python對函數式編程提供部分支持。由於Python允許使用變量,因此,Python不是純函數式編程語言。

一、定義

簡單說,"函數式編程"是一種"編程範式"(programming paradigm),也就是如何編寫程序的方法論。

主要思想是把運算過程盡量寫成一系列嵌套的函數調用。舉例來說,現在有這樣一個數學表達式:

  (1 + 2) * 3 - 4

傳統的過程式編程,可能這樣寫:

  var a = 1 + 2;

  var b = a * 3;

  var c = b - 4;

函數式編程要求使用函數,我們可以把運算過程定義為不同的函數,然後寫成下面這樣:

  var result = subtract(multiply(add(1,2), 3), 4);

這段代碼再演進以下,可以變成這樣

add(1,2).multiply(3).subtract(4)

這基本就是自然語言的表達了。再看下面的代碼,大家應該一眼就能明白它的意思吧:

merge([1,2],[3,4]).sort().search("2")

因此,函數式編程的代碼更容易理解。

要想學好函數式編程,不要玩py,玩Erlang,Haskell,lisp 好了,我只會這麽多了。。。


高階函數

變量可以指向函數,函數的參數能接收變量,那麽一個函數就可以接收另一個函數作為參數,這種函數就稱之為高階函數。

技術分享圖片
1 #!/usr/bin/env python
2 # -*- coding:utf-8 -*-      
3 #Author: nulige
4 
5 def add(a,b,f):
6     return f(a)+f(b)
7 
8 res = add(3,-6,abs)   #6+3=9
9 print(res)
技術分享圖片

執行結果:

1 9


實現字符串轉成字典功能

技術分享圖片
 1 >>> b = ‘‘‘ {
 2 ...             ‘bakend‘: ‘www.oldboy.org‘,
 3 ...             ‘record‘:{
 4 ...                 ‘server‘: ‘100.1.7.9‘,
 5 ...                 ‘weight‘: 20,
 6 ...                 ‘maxconn‘: 30
 7 ...             }
 8 ...         }‘‘‘
 9 >>> b
10 " {\n            ‘bakend‘: ‘www.oldboy.org‘,\n            ‘record‘:{\n                ‘server‘: ‘100.1.7.9‘,\n                ‘weight‘: 20,\n                ‘maxconn‘: 30\n            }\n        }"
11 >>> b[1]
12 ‘{‘
13 >>> eval(b)
14 {‘bakend‘: ‘www.oldboy.org‘, ‘record‘: {‘weight‘: 20, ‘maxconn‘: 30, ‘server‘: ‘100.1.7.9‘}}
15 >>> b=eval(b)
16 >>> b
17 {‘bakend‘: ‘www.oldboy.org‘, ‘record‘: {‘weight‘: 20, ‘maxconn‘: 30, ‘server‘: ‘100.1.7.9‘}}
18 >>> b[‘record‘]
19 {‘weight‘: 20, ‘maxconn‘: 30, ‘server‘: ‘100.1.7.9‘}
技術分享圖片

第四天 PYTHON 函數