1. Python 中的萬能之王 Lambda 函數(shù)

        共 4425字,需瀏覽 9分鐘

         ·

        2022-04-17 17:45


        Python 提供了非常多的庫和內(nèi)置函數(shù)。有不同的方法可以執(zhí)行相同的任務(wù),而在 Python 中,有個(gè)萬能之王函數(shù):lambda 函數(shù),它可以以不同的方式在任何地方使用。今天云朵君將和大家一起研究下這個(gè)萬能之王!

        Lambda 函數(shù)簡介

        Lambda函數(shù)也被稱為匿名(沒有名稱)函數(shù),它直接接受參數(shù)的數(shù)量以及使用該參數(shù)執(zhí)行的條件或操作,該參數(shù)以冒號(hào)分隔,并返回最終結(jié)果。為了在大型代碼庫上編寫代碼時(shí)執(zhí)行一項(xiàng)小任務(wù),或者在函數(shù)中執(zhí)行一項(xiàng)小任務(wù),便在正常過程中使用lambda函數(shù)。

        lambda?argument_list:expersion

        argument_list是參數(shù)列表,它的結(jié)構(gòu)與Python中函數(shù)(function)的參數(shù)列表是一樣的

        a,b
        a=1,b=2
        *args
        **kwargs
        a,b=1,*args

        ....

        expression是一個(gè)關(guān)于參數(shù)的表達(dá)式,表達(dá)式中出現(xiàn)的參數(shù)需要在argument_list中有定義,并且表達(dá)式只能是單行的。

        1
        None
        a+b
        sum(a)
        1?if?a?>10?else?0
        [i?for?i?in?range(10)]
        ...

        普通函數(shù)和Lambda函數(shù)的區(qū)別

        1. 沒有名稱
          Lambda函數(shù)沒有名稱,而普通操作有一個(gè)合適的名稱。
        2. Lambda函數(shù)沒有返回值
          使用def關(guān)鍵字構(gòu)建的普通函數(shù)返回值或序列數(shù)據(jù)類型,但在Lambda函數(shù)中返回一個(gè)完整的過程。假設(shè)我們想要檢查數(shù)字是偶數(shù)還是奇數(shù),使用lambda函數(shù)語法類似于下面的代碼片段。
        b?=?lambda?x:?"Even"?if?x%2==0?else?"Odd"
        b(9)
        1. 函數(shù)只在一行中
          Lambda函數(shù)只在一行中編寫和創(chuàng)建,而在普通函數(shù)的中使用縮進(jìn)
        2. 不用于代碼重用
          Lambda函數(shù)不能用于代碼重用,或者不能在任何其他文件中導(dǎo)入這個(gè)函數(shù)。相反,普通函數(shù)用于代碼重用,可以在外部文件中使用。

        為什么要使用Lambda函數(shù)?

        一般情況下,我們不使用Lambda函數(shù),而是將其與高階函數(shù)一起使用。高階函數(shù)是一種需要多個(gè)函數(shù)來完成任務(wù)的函數(shù),或者當(dāng)一個(gè)函數(shù)返回任何另一個(gè)函數(shù)時(shí),可以選擇使用Lambda函數(shù)。

        什么是高階函數(shù)?

        通過一個(gè)例子來理解高階函數(shù)。假設(shè)有一個(gè)整數(shù)列表,必須返回三個(gè)輸出。

        • 一個(gè)列表中所有偶數(shù)的和
        • 一個(gè)列表中所有奇數(shù)的和
        • 一個(gè)所有能被三整除的數(shù)的和

        首先假設(shè)用普通函數(shù)來處理這個(gè)問題。在這種情況下,將聲明三個(gè)不同的變量來存儲(chǔ)各個(gè)任務(wù),并使用一個(gè)for循環(huán)處理并返回結(jié)果三個(gè)變量。該方法常規(guī)可正常運(yùn)行。

        現(xiàn)在使用Lambda函數(shù)來解決這個(gè)問題,那么可以用三個(gè)不同的Lambda函數(shù)來檢查一個(gè)待檢驗(yàn)數(shù)是否是偶數(shù),奇數(shù),還是能被三整除,然后在結(jié)果中加上一個(gè)數(shù)。

        def?return_sum(func,?lst):
        ??result?=?0
        ??for?i?in?lst:
        ????#if?val?satisfies?func
        ????if?func(i):
        ??????result?=?result?+?i
        ??return?result
        lst?=?[11,14,21,56,78,45,29,28]
        x?=?lambda?a:?a%2?==?0
        y?=?lambda?a:?a%2?!=?0
        z?=?lambda?a:?a%3?==?0
        print(return_sum(x,?lst))
        print(return_sum(y,?lst))
        print(return_sum(z,?lst))

        這里創(chuàng)建了一個(gè)高階函數(shù),其中將Lambda函數(shù)作為一個(gè)部分傳遞給普通函數(shù)。其實(shí)這種類型的代碼在互聯(lián)網(wǎng)上隨處可見。然而很多人在使用Python時(shí)都會(huì)忽略這個(gè)函數(shù),或者只是偶爾使用它,但其實(shí)這些函數(shù)真的非常方便,同時(shí)也可以節(jié)省更多的代碼行。接下來我們一起看看這些高階函數(shù)。

        Python內(nèi)置高階函數(shù)

        Map函數(shù)

        map() 會(huì)根據(jù)提供的函數(shù)對(duì)指定序列做映射。

        Map函數(shù)是一個(gè)接受兩個(gè)參數(shù)的函數(shù)。第一個(gè)參數(shù) function 以參數(shù)序列中的每一個(gè)元素調(diào)用 function 函數(shù),第二個(gè)是任何可迭代的序列數(shù)據(jù)類型。返回包含每次 function 函數(shù)返回值的新列表。

        map(function,?iterable,?...)

        Map函數(shù)將定義在迭代器對(duì)象中的某種類型的操作。假設(shè)我們要將數(shù)組元素進(jìn)行平方運(yùn)算,即將一個(gè)數(shù)組的每個(gè)元素的平方映射到另一個(gè)產(chǎn)生所需結(jié)果的數(shù)組。

        arr?=?[2,4,6,8]?
        arr?=?list(map(lambda?x:?x*x,?arr))?
        print(arr)

        我們可以以不同的方式使用Map函數(shù)。假設(shè)有一個(gè)包含名稱、地址等詳細(xì)信息的字典列表,目標(biāo)是生成一個(gè)包含所有名稱的新列表。

        students?=?[
        ????????????{"name":?"John?Doe",
        ?????????????"father?name":?"Robert?Doe",
        ?????????????"Address":?"123?Hall?street"
        ?????????????},
        ????????????{
        ??????????????"name":?"Rahul?Garg",
        ??????????????"father?name":?"Kamal?Garg",
        ??????????????"Address":?"3-Upper-Street?corner"
        ????????????},
        ????????????{
        ??????????????"name":?"Angela?Steven",
        ?????????????"father?name":?"Jabob?steven",
        ?????????????"Address":?"Unknown"
        ????????????}
        ]
        print(list(map(lambda?student:?student['name'],?students)))
        >>>?['John?Doe',?'Rahul?Garg',?'Angela?Steven']

        上述操作通常出現(xiàn)在從數(shù)據(jù)庫或網(wǎng)絡(luò)抓取獲取數(shù)據(jù)等場景中。

        Filter函數(shù)

        Filter函數(shù)根據(jù)給定的特定條件過濾掉數(shù)據(jù)。即在函數(shù)中設(shè)定過濾條件,迭代元素,保留返回值為True 的元素。Map 函數(shù)對(duì)每個(gè)元素進(jìn)行操作,而 filter 函數(shù)僅輸出滿足特定要求的元素。

        假設(shè)有一個(gè)水果名稱列表,任務(wù)是只輸出那些名稱中包含字符“g”的名稱。

        fruits?=?['mango',?'apple',?'orange',?'cherry',?'grapes']?
        print(list(filter(lambda?fruit:?'g'?in?fruit,?fruits)))

        filter(function or None, iterable) --> filter object

        返回一個(gè)迭代器,為那些函數(shù)或項(xiàng)為真的可迭代項(xiàng)。如果函數(shù)為None,則返回為真的項(xiàng)。

        Reduce函數(shù)

        這個(gè)函數(shù)比較特別,不是 Python 的內(nèi)置函數(shù),需要通過from functools import reduce 導(dǎo)入。Reduce 從序列數(shù)據(jù)結(jié)構(gòu)返回單個(gè)輸出值,它通過應(yīng)用一個(gè)給定的函數(shù)來減少元素。

        reduce(function,?sequence[,?initial])?->?value

        將包含兩個(gè)參數(shù)的函數(shù)(function)累計(jì)應(yīng)用于序列(sequence)的項(xiàng),從左到右,從而將序列reduce至單個(gè)值。

        如果存在initial,則將其放在項(xiàng)目之前的序列,并作為默認(rèn)值時(shí)序列是空的。

        假設(shè)有一個(gè)整數(shù)列表,并求得所有元素的總和。且使用reduce函數(shù)而不是使用for循環(huán)來處理此問題。

        from?functools?import?reduce
        lst?=?[2,4,6,8,10]
        print(reduce(lambda?x,?y:?x+y,?lst))
        >>>?30

        還可以使用 reduce 函數(shù)而不是for循環(huán)從列表中找到最大或最小的元素。

        lst?=?[2,4,6,8]
        #?找到最大元素
        print(reduce(lambda?x,?y:?x?if?x>y?else?y,?lst))
        #?找到最小元素
        print(reduce(lambda?x,?y:?x?if?xelse?y,?lst))

        高階函數(shù)的替代方法

        列表推導(dǎo)式

        其實(shí)列表推導(dǎo)式只是一個(gè)for循環(huán),用于添加新列表中的每一項(xiàng),以從現(xiàn)有索引或一組元素創(chuàng)建一個(gè)新列表。之前使用map、filter和reduce完成的工作也可以使用列表推導(dǎo)式完成。然而,相比于使用Map和filter函數(shù),很多人更喜歡使用列表推導(dǎo)式,也許是因?yàn)樗菀讘?yīng)用和記憶。

        同樣使用列表推導(dǎo)式將數(shù)組中每個(gè)元素進(jìn)行平方運(yùn)算,水果的例子也可以使用列表推導(dǎo)式來解決。

        arr?=?[2,4,6,8]
        arr?=?[i**2?for?i?in?arr]
        print(arr)
        fruit_result?=?[fruit?for?fruit?in?fruits?if?'g'?in?fruit]
        print(fruit_result)

        字典推導(dǎo)式

        與列表推導(dǎo)式一樣,使用字典推導(dǎo)式從現(xiàn)有的字典創(chuàng)建一個(gè)新字典。還可以從列表創(chuàng)建字典。

        假設(shè)有一個(gè)整數(shù)列表,需要?jiǎng)?chuàng)建一個(gè)字典,其中鍵是列表中的每個(gè)元素,值是列表中的每個(gè)元素的平方。

        lst?=?[2,4,6,8]
        D1?=?{item:item**2?for?item?in?lst}
        print(D1)
        >>>?{2:?4,?4:?16,?6:?36,?8:?64}
        #?創(chuàng)建一個(gè)只包含奇數(shù)元素的字典
        arr?=?[1,2,3,4,5,6,7,8]
        D2?=?{item:?item**2?for?item?in?arr?if?item?%2?!=?0}
        print(D2)
        >>>?{1:?1,?3:?9,?5:?25,?7:?49}

        一個(gè)簡單應(yīng)用

        如何快速找到多個(gè)字典的公共鍵

        方法一

        dl?=?[d1,?d2,?d3]?#?d1,?d2,?d3為字典,目標(biāo)找到所有字典的公共鍵
        [k?for?k?in?dl[0]?if?all(map(lambda?d:?k?in?d,?dl[1:]))]
        dl?=?[{1:'life',?2:?'is'},?
        ??????{1:'short',?3:?'i'},?
        ??????{1:?'use',?4:?'python'}]
        [k?for?k?in?dl[0]?if?all(map(lambda?d:?k?in?d,?dl[1:]))]
        #?1
        解析
        #?列表表達(dá)式遍歷dl中第一個(gè)字典中的鍵
        [k?for?k?in?dl[0]]
        #?[1,?2]

        #?lambda?匿名函數(shù)判斷字典中的鍵,即k值是否在其余字典中
        list(map(lambda?d:?1?in?d,?dl[1:]))
        #?[True,?True]
        list(map(lambda?d:?2?in?d,?dl[1:]))
        #[False,?False]

        #?列表表達(dá)式條件為上述結(jié)果([True,?True])全為True,則輸出對(duì)應(yīng)的k值
        #1

        方法二

        #?利用集合(set)的交集操作
        from?functools?import?reduce
        #?reduce(lambda?a,?b:?a*b,?range(1,11))?#?10!
        reduce(lambda?a,?b:?a?&?b,?map(dict.keys,?dl))

        寫在最后

        目前已經(jīng)學(xué)習(xí)了Lambda函數(shù)是什么,以及Lambda函數(shù)的一些使用方法。隨后又一起學(xué)習(xí)了Python中的高階函數(shù),以及如何在高階函數(shù)中使用lambda函數(shù)。除此之外,還學(xué)習(xí)了高階函數(shù)的替代方法:在列表推導(dǎo)式和字典推導(dǎo)式中執(zhí)行之前操作。雖然這些方法看似簡單,或者說你之前已經(jīng)見到過這類方法,但你很可能很少使用它們。你可以嘗試在其他更加復(fù)雜的函數(shù)中使用它們,以便使代碼更加簡潔。

        -?END -
        對(duì)比Excel系列圖書累積銷量達(dá)15w冊(cè),讓你輕松掌握數(shù)據(jù)分析技能,可以在全網(wǎng)搜索書名進(jìn)行了解選購
        瀏覽 49
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
          
          

            1. 麻豆熟妇乱妇熟色A片在线看 | 插菊花综合网3 | 国产精品无码一区二区三区男男 | 瑟瑟爱视频 | 女子口述高潮全过程 |