Python進階篇——lambda、map、filter、reduce高級函數的使用

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 參數列表:參數表達式
  1. 匿名函數,肯定是沒有名字的,我們可以將它賦給一個對象,然後通過這個對象就可以實現函數功能
    sum_n = lambda x,y:x+y
    
    print(sum_n(1,2))
    
    # 輸出結果:
    # 3
  2. 通過上面我們可以知道,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
  3. 同樣的道理,我們應該可以將其賦給另一個函數
    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
  4. 有一個邪惡的想法,如果我將lambda函數賦值給其他函數,那麼會發生什麼呢?
    print = lambda x:None
    
    print('test')
    
    # 輸出結果:
    # 什麼都沒發生

    那麼這就有了一個引申用法,我是否可以通過它來屏蔽某些函數功能;

那麼,有優點就肯定有缺點,我們一一說一下:

  1. 主體是表達式,那麼函數功能就不會非常複雜,只能夠實現簡單的功能;
  2. 在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用函數進行處理,得出最後的結果

我們可以理解成滾雪球,不斷根據規則進行迭代處理,到最後一個元素處理完畢得到最終結果。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章