高階函數
滿足兩個條件任意一個都是高階函數
1.接受函數作為參數的函數
2.將函數作為返回值的函數
當我們使用一個函數作為參數時,實際上我們就是將指定的代碼傳遞給了目標函數
l = [1,2,3,4,5,6]
def fn(n):
if n %2 ==0:
return True
return False
def func(func,lst):
new_lst = []
for i in lst:
if fn(i)==True:
new_lst.append(i)
return new_lst
print(func(fn,l))
>>>[2, 4, 6]
filter() 可以從序列中過濾出來符合條件的元素,保存到一個新的序列當中
參數:1.函數,根據該函數來過濾序列(可迭代結構)
?????????? 2. 需要過濾的序列(可迭代結構)
返回值:過濾后新的序列
l = [1,2,3,4,5,6]
def fn(n):
if n %2 ==0:
return True
return False
print(filter(fn,l))
print(list(filter(fn,l)))
>>><filter object at 0x0000021D6929E278>
>>>[2, 4, 6]
匿名函數
匿名函數 lambda表達式
lambda函數表達式是用來創(chuàng)建一些簡單的函數 它是函數創(chuàng)建的另外一種方式
語法:lambda 參數列表:返回值
匿名函數最大的好處是只會調用一次,用完之后會從內存消失
匿名函數一般作為參數使用
print(lambda a,b:a+b)
>>><function <lambda> at 0x000001C77671DF28>
print(fn)
>>><function fn at 0x000001DB1E711E18>
# 比較后 可以發(fā)現(xiàn) lambda表達式創(chuàng)建的函數 沒有名字。。
調用匿名函數
print((lambda a,b:a+b)(1,2))
>>>3
func = lambda a,b:a+b
print(func(1,2))
>>>3
再返回到filter那里
#我們用lambda表達式來替代fn函數
#因為fn函數比較簡單 功能單一 且只調用一次 不會再調用 也不想讓fn函數在全局作用域當中
print(list(filter(lambda i:i%2==0,l)))
>>>[2, 4, 6]
map()函數可以對 可迭代對象 中所有元素做指定的操作,然后將其添加到一個新的對象中返回
l = [1,2,3,4,5,6]
result = map(lambda i:i+1,l)
print(list(result))
>>>[2, 3, 4, 5, 6, 7]
sort()函數可以對列表當中的元素進行排序(列表對象 調用)
sort函數有一個關鍵字 key 需要一個函數作為參數
lst = ['e','cc','dd','bbb','aaaa']
lst.sort(key=len ) #len()函數
print(lst)
>>>['e', 'cc', 'dd', 'bbb', 'aaaa']
lst = [1,2,'3','5',0]
lst.sort(key=int) #int()函數
print(lst)
>>>[0, 1, 2, '3', '5']
sorted(_iterable,key,reverse) 會返回一個新的列表
iterable 可迭代的
reverse 反轉
lst = [1,2,'3','5',0]
l = sorted(lst,key=int)
print('排序前',lst)
print('排序后',l)
>>>排序前 [1, 2, '3', '5', 0]
>>>排序后 [0, 1, 2, '3', '5']
- 閉包
將函數作為返回值返回 也是一種高階函數
通過閉包可以創(chuàng)建一些只有當前函數才能訪問的對象,還可以將一些私有的數據藏到閉包中
def fn():
#函數內部在定義一個函數
def fn2():
print("fn2")
#在內部函數將fn2作為返回值返回
return fn2
print(fn())
fn()()
>>><function fn.<locals>.fn2 at 0x000001710661DF28>
>>>fn2
nums = [10,10,20,30,20]
print(sum(nums)/len(nums))
>>>18.0
nums = []
def fn(num):
nums.append(num)
print(sum(nums)/len(nums))
fn(10)
fn(10)
fn(20)
fn(20)
>>>10.0
>>>10.0
>>>13.333333333333334
>>>15.0
#但是這種方式 nums為全局變量 不安全 因此引出了閉包
形成閉包的條件:
1.函數嵌套
2.將內部函數作為返回值返回
3.內部函數必須使用到外部函數的變量
什么時候使用到閉包
當你的某些數據不希望被外界訪問和修改的時候 就需要用到閉包
這樣能夠保證數據的安全性
- 引入裝飾器
def add(a,b):
print("計算開始")
r = a+b
print("計算結束")
return r
def mul(a,b):
print("計算開始")
r = a*b
print("計算結束")
print(add(1,2))
print(mul(1,2))
#我們可以通過修改函數中的代碼來完成,但是會產生一些問題
#1.修改的函數很多
#2.不方便后期的維護
#3.會違背開閉原則(ocp) 程序設計 要求對程序的擴展,但是要關閉對程序的更新
下面這種寫法就是對程序擴展而不更新 但是不能每調用一個方法 寫一個這種函數
def add(a,b):
r = a+b
return r
def mul(a,b):
r = a*b
return r
def new_add(a,b):
print("計算開始")
r = add(a,b)
print("計算結束")
return r
print(new_add(1,2))
于是有了裝飾器
def start_end(func):
def new_func(*args,**kwargs): #裝包
print("程序開始")
res=func(*args,*kwargs) #解包
print("程序結束")
return res
return new_func
def add(a,b):
return a + b
def pr():
print("Hello")
print(start_end(add)(1,2))
start_end(pr)()
>>>程序開始
>>>程序結束
>>>3
>>>程序開始
>>>Hello
>>>程序結束
def start_end(func):
def new_func(*args,**kwargs): #裝包
print("程序開始")
res=func(*args,*kwargs) #解包
print("程序結束")
return res
return new_func
@start_end
def add(a,b):
return a + b
print(add(1,2))
@start_end
def pr():
print("Hello")
pr()
>>>程序開始
>>>程序結束
>>>3
>>>程序開始
>>>Hello
>>>程序結束
#start_end(func) 類似這樣的函數其實就是一個裝飾器
#在開發(fā)中,都是通過裝飾器來擴展函數的功能