函數式編程
是指用一系列函數解決問題
要求:def創建的函數最好不要訪問局部作用域以外的變量,這樣可以保證返回結果的唯一性
函數是一等公民(Guido)
1. 函數本身可以賦值給變量,賦值後變量綁定函數
2. 允許將函數本身作爲參數傳入另一個函數
3. 允許函數返回一個函數
好處:
1.用每一個函數完成細小的功能,一系列函數在任意組合可以完成大問題
2.函數僅接受輸入併產生輸入,不包含任何能影響輸出的內部狀態
函數的可重入性:
當一個函數在運行時不讀取和改變除局部作用域以外的變量時,此函數爲可重入函數
可重入函數在每次調用時,如果參數一定,則結果必然一定
示例:
可重入函數:
def add1(x, y):
return x + y
不可重入函數示例:
y = 200
def add2(x):
return x + y
print(add2(10)) # 210
y = 300
print(add2(10)) # 310
高階函數 high order function
什麼是高階函數
滿足下列條件中一個的函數即爲高階函數
1. 函數接收一個或多個函數作爲參數傳入
2. 函數返回一個函數
python中內建的高階函數:
map, filter, sorted
map 函數
map(func, *iterables) 用函數和對可迭代對象中的每一個元素作爲參數返回新的可迭代對象.當最短的一個可迭代對象不再提供數據時迭代結束
要求:
func函數接收的參數個數必須與可迭代對象的個數相同
示例見:
map.py
練習 :
1. 求 1**2 + 2**2 + 3**2 + ...+ 9**2的和
(用函數式和高階函數map實現)
2. 求 1**3 + 2**3 + 3**3 + ...+ 9**3的和
3. 求: 1**9 + 2**8 + 3**7 + .... + 9**1的和
filter 函數:
格式:
filter(function, iterable)
作用:
篩選可迭代對象iterable中的數據,返回一個可迭代對象,此可迭代對象將對iterable提供的數據進行篩選
說明:
函數function 將對iteralbe中的每個元素進行求布爾值,返回True則保留,返回False則丟棄
示例見:
filter.py
練習:
1. 把之前寫的is_prime(x)判斷x是否爲素數的函數複製過來
1) 用filter函數把100到200的全部素數求出來,放入列表L中
2) 求300 ~ 400之間全部素數的和
sorted 函數
作用:
將原可迭代對象提供的數據進行排序,生成排序後的列表
格式:
sorted(iterable, key(必須是key)=None, reverse=False)
說明:
iterable 可迭代對象
key 函數是用來提供一個排序參考值的函數,這個函數的返回值將作爲排序的依據
reverse 標誌用來設置是否降序排序
示例:
L = [5, -2, -4, 0, 3, 1]
L2 = sorted(L) # [-4, -2, 0, 1, 3, 5]
# 要得到這樣的結果該怎麼辦?
L3 = sorted(L, key=abs) # [0, 1, -2, 3, -4, 5]
names = ['Tom', 'Jerry', 'Spike', 'Tyke']
# 結果 ['Tom', 'Tyke', 'Jerry', 'Spike']
L = sorted(names, key=len)
練習:
已知:
names = ['Tom', 'Jerry', 'Spike', 'Tyke']
排序的依據爲原字符串反序的字符串
'moT', 'yrreJ', 'ekipS', 'ekyT'
結果:
['Spike', 'Tyke', 'Tom', 'Jerry']
遞歸函數 recursion
函數直接或間接的調用自身
示例:
def f():
f() # 直接調用自己,進入遞歸
f()
# 函數間接調用自身
def fa():
fb()
def fb():
fa()
fa()
print("遞歸完成")
說明:
遞歸一定要控制遞歸的層數,當符合一定條件時要終止遞歸調用
幾乎所有的遞歸都能用while循環來代替
優點:
遞歸可以把問題簡單化,讓思路更爲清晰,代碼更簡潔
缺點:
遞歸因系統環境影響大,當遞歸深度太大時,可能會得到不可預知的結果
遞歸的兩個階段:
遞推階段: 從原問題出發,按遞歸公式遞推從未知到已知,最終達到遞歸的終止條件
迴歸階段: 按遞歸終止條件求出結果,逆向逐步代入遞歸公式,迴歸到問題求解
示例見:
recursion.py
示例:
寫一個函數求n的階乘(遞歸實現)
見:
recursion_factorial.py
遞歸的實現方法
先假設函數已經實現
練習:
寫一個函數mysum(n), 用遞歸方法求
1 + 2 + 3 + 4 + .... + n的和
def mysum(n):
....
print(mysum(100)) # 5050
閉包 closure
閉包是指引用了此函數外部嵌套函數作用域變量的函數
閉包必須滿足三個條件:
1. 必須有內嵌函數
2. 內嵌函數必須引用外部函數中的變量
3. 外部函數返回值必須是內嵌函數.