OK,我們今天來簡單講一下Python中的幾個高級函數,爲什麼說這是高級函數呢?因爲它可以極大的減少我們的代碼量,讓我們的代碼看起來更加的清爽,提高我們的開發速度;
用lambda創建匿名函數
在理解匿名函數之前,我們先來回顧下我們之前創建函數是怎麼創建的:
def 函數名(參數1,參數2[,……]):
函數主體
return 返回值
標標準準的函數構建方法,但是有一個問題,當我們創建的函數只需要計算兩個數相加之和時,我們最少也要寫兩行代碼:
def sum_n(x,y):
return x+y
而用lambda創建則只需要一行代碼就可以搞定:
sum_n = lambda x,y:x+y
這個就是lambda的魅力所在,使用也是非常的簡單,接下來我們就來講解一下它的使用方法和優缺點:
lambda 參數列表:參數表達式
- 匿名函數,肯定是沒有名字的,我們可以將它賦給一個對象,然後通過這個對象就可以實現函數功能
sum_n = lambda x,y:x+y print(sum_n(1,2)) # 輸出結果: # 3
- 通過上面我們可以知道,lambda其主體就是一個表達式,既然可以賦給一個對象,那麼我們可不可以賦給列表,當列表元素呢?
func = [lambda x,y:x+y,lambda x,y:x-y,lambda x,y:x*y,lambda x,y:x/y] for fun in func: print(fun(1,2)) # 輸出結果: # 3 # -1 # 2 # 0.5
- 同樣的道理,我們應該可以將其賦給另一個函數
sum_n = lambda x,y:x+y def sum_m(func,x,y,n): return func(x,y)-n print(sum_m(sum_n,1,2,6)) # 輸出結果: # -3
- 有一個邪惡的想法,如果我將lambda函數賦值給其他函數,那麼會發生什麼呢?
print = lambda x:None print('test') # 輸出結果: # 什麼都沒發生
那麼這就有了一個引申用法,我是否可以通過它來屏蔽某些函數功能;
那麼,有優點就肯定有缺點,我們一一說一下:
- 主體是表達式,那麼函數功能就不會非常複雜,只能夠實現簡單的功能;
- 在lambda中,是不支持異常處理的,那麼當處理異常時,程序就會崩潰:
sum_n = lambda x,y:x+y sum_n(1,'a') # 輸出結果: # TypeError: unsupported operand type(s) for +: 'int' and 'str'
用map函數做函數功能的序列映射
這是什麼意思呢?我們下面來舉個栗子說明:
a = [1,2,3,4,5]
b = [3,5,6,2,7]
n = []
for i in range(5):
n.append(a[i]+b[i])
print(n)
# 輸出結果:
# [4, 7, 9, 6, 12]
我們正常來講,想要將兩個列表元素依次相加,需要這麼幾行代碼,但是用map函數就方便啦:
def sum_n(x,y):
return x+y
print(list(map(sum_n,[1,2,3,4,5],[3,5,6,2,7])))
# 輸出結果:
# [4, 7, 9, 6, 12]
額,好像沒有啥差別呀,不就是沒用變量傳參了嘛;不要着急,還記得lambda嘛,實現一行解決問題:
print(list(map(lambda x,y:x+y,[1,2,3,4,5],[3,5,6,2,7])))
# 輸出結果:
# [4, 7, 9, 6, 12]
是不是很神奇,OK,現在要敲黑板了,我們來總結一下:
map函數可以根據我們指定的函數功能,將若干序元素依次進行處理,最後返回的也是一個序列集合;
那麼現在都是序列元素個數對等的情況,如果元素個數不對等會怎麼樣呢?
print(list(map(lambda x,y:x+y,[1,2,3,4,5],[3,5,6])))
# 輸出結果:
# [4, 7, 9]
我們可以發現,沒有報錯,只進行了前三個元素處理;那麼,我們可以得出,當序列元素不對等時,不對等部分就不會進行處理。
用filter函數對序列進行過濾
這個函數功能從字面上應該就可以理解,它就相當於一個篩子,可以將不符合要求的序列元素過濾掉,然後返回一個新的序列;
a = [1,2,3,4,5,6,7,8,9]
print(list(filter(lambda x:x%2==1,a)))
# 輸出結果:
# [1, 3, 5, 7, 9]
從上面栗子的結果可以看出,上面的功能就是篩選出序列中所有的奇數,接下來我們講解下函數的參數:
filter(判斷函數,源序列))
# 判斷函數的返回值我們就可以理解成判斷條件
下面我們再來舉個栗子:
import math
print(list(filter(lambda x:math.sqrt(x)%1==0,range(1,100))))
# lambda x:math.sqrt(x)%1==0
# 這裏的x就是判斷值
# math.sqrt(x)%1==0 就是判斷條件
# range(1,100) 就是要進行篩選的源序列
# 輸出結果:
# [1, 4, 9, 16, 25, 36, 49, 64, 81]
用reduce函數累計處理序列元素
這個函數還是還是不好理解的,下面我來舉個栗子:
from functools import reduce # 在Python3中我們不能直接拿來使用,要從functools中導入使用
print(reduce(lambda x,y:x+y,range(1,101)))
# 輸出結果:
# 5050
上面的栗子就是非常經典的累加,將1-100的數字依次相加,最後得出一個結果:
reduce(處理函數,[a,b,c,d,e])
# 首先對a和b用函數進行處理,得出結果b1
# 然後對b1和c用函數進行處理,得出c1
# 一次類推
# 最後對d1和e用函數進行處理,得出最後的結果
我們可以理解成滾雪球,不斷根據規則進行迭代處理,到最後一個元素處理完畢得到最終結果。