01.- 函數 - 匿名函數
1.filter(fnuction,iterable) --> filter(函數,可迭代的) -->filter(函數,序列)
可以從序列當中過濾出符合條件的元素,保存到一個新的序列當中
參數一 : 傳遞函數 參數二 : 需要過濾的序列
返回值 過濾後新的序列
# 定義一個函數 可以將指定列表當中的所有偶數,保存到一個新的列表中返回
l = [1,2,3,4,5,6,7,8,9,10]
# 定義一個函數,用來檢測一個任意的偶數
def fn2(i):
if i % 2 == 0:
return True
# 定義一個函數,用來檢測指定數字是否大於5
def fn3(i):
if i > 5:
return True
return False
# 創建一個新的列表
new_list = []
# 定義一個函數
def fn4(i):
if i % 3 == 0:
return True
return False
def fn(func,lst): # 傳一個變量 n
for n in lst:
# 判斷 n 的奇偶
# if not fn2(n): # [2, 4, 6, 8, 10]
# if fn3(n): # [6, 7, 8, 9, 10]
if func(n): # [2, 4, 6, 8, 10]
new_list.append(n)
# 返回新的列表
return new_list
print(fn(fn4,l)) # [3, 6, 9]
# 當我們使用一個函數作爲參數時,實際上是將指定的代碼傳遞進了目標函數
print(filter(fn4,l)) # <filter object at 0x000002570D6966D8>
print(list(filter(fn4,l))) # [3, 6, 9]
2.lambda表達式
lambda函數表達式專門用來創建一些簡單的函數,它是函數創建的另一種方式
語法 lambda 參數列表[a,b,c…] : 返回值
((lambda a,b : a+b)(10,20) 一般不這麼寫
print(fn5(123,456)) # 579
print(lambda a,b : a+b) # <function <lambda> at 0x00000130CEA1B2F0> 打印結果比一般的打印結果少個名稱,所以才叫做匿名函數
print((lambda a,b : a+b)(10,20)) # 30 一般不這麼寫
def fn5(a,b):
return a + b
fn6 = lambda a,b: a+b
print(fn6(30,20)) # 50 一般這麼寫
3.lambda函數表達式的應用
l = [1,2,3,4,5,6,7,8,9,10]
# def fn(i):
# return i % 3 == 0
# lambda i : i % 3 == 0
r = filter(lambda i : i > 5,l)
print(list(r))
>>>[6,7,8,9,10]
4. map()
map()函數可以對可迭代對象中所有的元素做指定操作,然後將其添加到一個新的對象返回
= [1,2,3,4,5,6,7,8,9,10]
r = map(lambda i : i + 1,l) # 匿名函數一般都是作爲參數使用,其他地方一般不用
print(list(r)) # [2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
5. sort()函數
該方法用來對列表當中的元素進行排序
sort()方法是直接默認比較列表中元素的大小
l = ['bb','aaaa','c','fff','dddddddd']
l.sort() # sort()直接默認:比較列表中元素的大小
print(l) # ['aaaa', 'bb', 'c', 'dddddddd', 'fff']
6.在sort()函數中可以接收一個關鍵字參數 key
key需要一個函數作爲參數
l = ['bb','aaaa','c','fff','dddddddd']
l.sort(key=len) # 對列表中的字符串長度進行一個排序
print(l) # ['c', 'bb', 'fff', 'aaaa', 'dddddddd']
7.如果要將數字和字符串比較大小,就要用到l.sort(key=int)
l = [2,3,'1',3,'5',4]
l.sort(key=int)
print(l) # ['1', 2, 3, 3, 4, '5']
8. sorted()
sorted() 它有返回值, 會返回一個新的列表
l = [2,3,'1',3,'5',4]
print('排序前:',l)
sorted(l,key=int)
print('排序後:',l)
>>>
排序前: [2, 3, '1', 3, '5', 4]
排序後: [2, 3, '1', 3, '5', 4]
對sorted()進行打印之後會出現一個結果,這個表示sorted()函數有返回值,打印之後會返回一個新的排好順序的列表
l = [2,3,'1',3,'5',4]
print('排序前:',l)
print(sorted(l,key=int)) # 對sorted()進行打印之後會出現一個結果,這個表示sorted()函數有返回值,打印之後會返回一個新的排好順序的列表
print('排序後:',l)
>>>
排序前: [2, 3, '1', 3, '5', 4]
['1', 2, 3, 3, 4, '5']
排序後: [2, 3, '1', 3, '5', 4]
02. - 函數 - 閉包
1.閉包含義:將函數作爲返回值返回也是一種高階函數,俗稱閉包
def fn():
# 在函數內部再定義一個函數
def inner():
print('我是fn2')
# 將函數內部 inner()作爲返回值
return inner
print(fn) # <function fn at 0x00000155A7683EA0>
print(fn()) # <function fn.<locals>.inner at 0x000001A045CE3E18>
def fn():
a = 10
# 在函數內部再定義一個函數
def inner():
print('我是fn2',a)
# 將函數內部 inner()作爲返回值
return inner
# r是一個函數,是調用fn()後返回的函數
# 這個函數fn()內部定義的,並不是全局函數
# 所以這個函數總是能訪問到fn()函數內部的變量
r = fn()
r() # 我是fn2 10
所以這個函數總是能訪問fn()函數的內部變量
print(a) # NameError: name 'a' is not defined (名稱錯誤:未定義名稱“a”),在這個函數
裏面找不到一個定義名稱爲 a的變量,是因爲 變量a 處在一個函數的環境是閉包的一個函數中.
2. 創建閉包的好處是什麼?
通過閉包可以創建一些只有當前函數可以訪問到的變量(可以將一些私有的數據藏到閉包當中)
(1).求多個數的平均值(常規操作)
nums = [50,20,30,10,77]
print(sum(nums)/len(nums))
(2). 求多個數的平均值(高級操作)
# 定義一個函數,用來求平均值
def make_average():
#創建一個空的列表
nums = []
# 創建一個函數,用來接收元素,來求平均值,
def average(n):
# 將元素添加到列表裏面
nums.append(n)
# 求平均值
return sum(nums)/len(nums)
# 返回一個函數對象
return average
average = make_average()
print(average(10)) # 10.0
print(average(20)) # 15.0
nums = [] # 清空列表依然對函數沒有什麼影響
print(average(60)) # 30.0
(3). 總結:形成閉包的條件:
1.函數嵌套
2.將內部函數作爲返回值返回
3.內部函數必須要使用到外部函數的變量
(4). 什麼時候用閉包呢?
當你有些數據不希望別人訪問,不希望別人修改的時候,就需要用到閉包,這樣能確保我們的數據安全
03. - 函數 - 裝飾器引入
# 打印開始計算,打印計算結束
def add(a,b):
# 求任意兩個數的和
print('計算開始...')
r = a + b
print('計算結束...')
return r
def mul(a,b):
# 求任意兩個數的積
return a * b
r = add(1,2) # 3
r = mul(1,2) # 2
print(r)
1.通過剛纔以上的步驟來實現當前的這個需要,我們發現了以下一些問題
(1).如果需要修改的函數過多,修改起來比較麻煩
(2).不方便後期維護
(3).這樣會違反一個開閉原則(ocp)
(4).我們在開發的時候,要求可以開發對程序的擴展,但是要關閉對程序的修改
改善後的程序:
# 打印開始計算,打印計算結束
def add(a,b):
# 求任意兩個數的和
r = a + b
return r
def mul(a,b):
# 求任意兩個數的積
return a * b
r = add(1,2)
r = mul(1,2)
# 在不修改原函數的情況下,來對函數進行擴展
def fn():
print('我是fn函數')
# 我創建一個新的函數
def fn2():
print('函數開始執行......')
fn()
print('函數執行結束......')
# fn2()
def new_add(a,b):
print('函數開始執行......')
r = add(a,b)
print('函數執行結束......')
return r
r = new_add(1,2)
print(r)
>>>
函數開始執行......
函數執行結束......
3
04. - 函數 - 裝飾器的使用
1. 引導
# 打印開始計算,打印計算結束
def add(a,b):
# 求任意兩個數的和
# print('計算開始...')
r = a + b
# print('計算結束...')
return r
def mul(a,b):
# 求任意兩個數的積
return a * b
r = add(1,2) # 3
r = mul(1,2) # 2
# print(r)
def start_end(old):
# 用來對其他函數進行擴展,是其他函數可以在執行前打印執行開始,執行後打印執行結束
# 創建一個函數
def new_function(a,b):
print('開始執行......')
# 調用被擴展的函數
result = old(a,b)
print('開始結束......')
return result
# 返回函數
return new_function
f = start_end(add)
r = f(1,2)
print(r)
>>>
開始執行......
開始結束......
3
2.接下來我們要用函數裝飾器來對任何函數進行一個擴展(例如關鍵字參數,位置參數,一百個各種各樣五花八門的函數),這個時候就需要用到一個一個參數 : args
*args : 接收的是所有的位置參數 ; **kwargs : 接受所有的關鍵字參數
# 在不修改原函數的情況下,來對函數進行擴展
def fn():
print('我是fn函數')
# 我創建一個新的函數
def fn2():
print('函數開始執行......')
fn()
print('函數執行結束......')
# fn2()
def new_add(a,b):
print('函數開始執行......')
r = add(a,b)
print('函數執行結束......')
return r
def start_end(old):
# 用來對其他函數進行擴展,是其他函數可以在執行前打印執行開始,執行後打印執行結束
# 創建一個函數 *args 接收的是所有的位置參數 **kwargs 接受所有的關鍵字參數
def new_function(*args,**kwargs):
print('開始執行......')
# 調用被擴展的函數
result = old(*args,**kwargs)
print('開始結束......')
return result
# 返回函數
return new_function
f = start_end(fn)
r = f()
print(r)
>>>
開始執行......
我是fn函數
開始結束......
None
3. 像 start_end(old) 這種函數我們就稱之爲裝飾器
通過裝飾器 可以在不修改原來函數的基礎之上來歲函數進行擴展
在開發當中,我們都是通過裝飾器來擴展函數的功能
(1)
# 打印開始計算,打印計算結束
def add(a,b):
# 求任意兩個數的和
# print('計算開始...')
r = a + b
# print('計算結束...')
return r
def mul(a,b):
# 求任意兩個數的積
return a * b
r = add(1,2) # 3
r = mul(1,2) # 2
(2)
# 在不修改原函數的情況下,來對函數進行擴展
def fn():
print('我是fn函數')
# 我創建一個新的函數
def fn2():
print('函數開始執行......')
fn()
print('函數執行結束......')
# fn2()
def new_add(a,b):
print('函數開始執行......')
r = add(a,b)
print('函數執行結束......')
return r
(3)
ef start_end(old):
# 用來對其他函數進行擴展,是其他函數可以在執行前打印執行開始,執行後打印執行結束
# 創建一個函數 *args 接收的是所有的位置參數 **kwargs 接受所有的關鍵字參數
def new_function(*args,**kwargs):
print('開始執行......')
# 調用被擴展的函數
result = old(*args,**kwargs)
print('開始結束......')
return result
# 返回函數
return new_function
f = start_end(fn)
f2 = start_end(add)
# r = f()
r = f2(123,456)
print(r)
>>>
開始執行......
開始結束......
579