<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Python中常用最神秘的函數(shù)! lambda 函數(shù)深度總結(jié)!

          共 7370字,需瀏覽 15分鐘

           ·

          2022-08-11 20:10


          今天我們來學(xué)習(xí) Python 中的 lambda 函數(shù),并探討使用它的優(yōu)點(diǎn)和局限性

          Let's do it!

          什么是 Python 中的 Lambda 函數(shù)

          lambda 函數(shù)是一個(gè)匿名函數(shù)(即,沒有名稱定義),它可以接受任意數(shù)量的參數(shù),但與普通函數(shù)不同,它只計(jì)算并返回一個(gè)表達(dá)式

          Python 中的 lambda 函數(shù)使用以下語法表達(dá):

          lambda 參數(shù):表達(dá)式

          lambda 函數(shù)包括三個(gè)元素:

          • 關(guān)鍵字 lambda:與普通函數(shù)中 def 類似
          • 參數(shù):支持傳遞位置和關(guān)鍵字參數(shù),與普通函數(shù)一樣
          • 正文:處理定參數(shù)的表達(dá)式

          需要注意的是,普通函數(shù)不同,這里不需要用括號將 lambda 函數(shù)的參數(shù)括起來,如果 lambda 函數(shù)有兩個(gè)或更多參數(shù),我們用逗號列出它們

          我們使用 lambda 函數(shù)只計(jì)算一個(gè)短表達(dá)式(理想情況下,單行)并且只計(jì)算一次,這意味著我們以后不會再復(fù)用這個(gè)函數(shù)。通常來說我們會將 lambda 函數(shù)作為參數(shù)傳遞給高階函數(shù)(接受其他函數(shù)作為參數(shù)的函數(shù)),例如 Python 內(nèi)置函數(shù),如 filter()、map() 或 reduce()等

          Python 中的 Lambda 函數(shù)如何工作

          讓我們看一個(gè)簡單的 lambda 函數(shù)示例:

          lambda x: x + 1

          Output:

          <function __main__.<lambda>(x)>

          上面的 lambda 函數(shù)接受一個(gè)參數(shù),將其遞增 1,然后返回結(jié)果

          它是以下帶有 def 和 return 關(guān)鍵字的普通函數(shù)的更簡單版本:

          def increment_by_one(x):
              return x + 1

          到目前我們的 lambda 函數(shù) lambda x: x + 1 只創(chuàng)建一個(gè)函數(shù)對象,不返回任何內(nèi)容,這是因?yàn)槲覀儧]有為其參數(shù) x 提供任何值(參數(shù))。讓我們先分配一個(gè)變量,將它傳遞給 lambda 函數(shù),看看這次我們得到了什么:

          a = 2
          print(lambda x: a + 1)

          Output:

          <function <lambda> at 0x00000250CB0A5820>

          我們的 lambda 函數(shù)沒有像我們預(yù)期的那樣返回 3,而是返回了函數(shù)對象本身及其內(nèi)存位置,可以看出這不是調(diào)用 lambda 函數(shù)的正確方法。要將參數(shù)傳遞給 lambda 函數(shù),執(zhí)行它并返回結(jié)果,我們應(yīng)該使用以下語法:

          (lambda x: x + 1)(2)

          Output:

          3

          雖然我們的 lambda 函數(shù)的參數(shù)沒有用括號括起來,但當(dāng)我們調(diào)用它時(shí),我們會在 lambda 函數(shù)的整個(gè)構(gòu)造以及我們傳遞給它的參數(shù)周圍添加括號

          上面代碼中要注意的另一件事是,使用 lambda 函數(shù),我們可以在創(chuàng)建函數(shù)后立即執(zhí)行該函數(shù)并接收結(jié)果。這就是所謂的立即調(diào)用函數(shù)執(zhí)行(或 IIFE)

          我們可以創(chuàng)建一個(gè)帶有多個(gè)參數(shù)的 lambda 函數(shù),在這種情況下,我們用逗號分隔函數(shù)定義中的參數(shù)。當(dāng)我們執(zhí)行這樣一個(gè) lambda 函數(shù)時(shí),我們以相同的順序列出相應(yīng)的參數(shù),并用逗號分隔它們:

          (lambda x, y, z: x + y + z)(381)

          Output:

          12

          也可以使用 lambda 函數(shù)來執(zhí)行條件操作。下面是一個(gè)簡單 if-else 函數(shù)的 lambda 模擬:

          print((lambda x: x if(x > 10else 10)(5))
          print((lambda x: x if(x > 10else 10)(12))

          Output:

          10
          12

          如果存在多個(gè)條件(if-elif-...-else),我們必須嵌套它們:

          (lambda x: x * 10 if x > 10 else (x * 5 if x < 5 else x))(11)

          Output:

          110

          但是上面的寫法,又令代碼變得難以閱讀

          在這種情況下,具有 if-elif-...-else 條件集的普通函數(shù)將是比 lambda 函數(shù)更好的選擇。實(shí)際上,我們可以通過以下方式編寫上面示例中的 lambda 函數(shù):

          def check_conditions(x):
              if x > 10:
                  return x * 10
              elif x < 5:
                  return x * 5
              else:
                  return x

          check_conditions(11)

          Output:

          110

          盡管上面的函數(shù)比相應(yīng)的 lambda 函數(shù)增加了更多行,但它更容易閱讀

          我們可以將 lambda 函數(shù)分配給一個(gè)變量,然后將該變量作為普通函數(shù)調(diào)用:

          increment = lambda x: x + 1
          increment(2)

          Output:

          3

          但是根據(jù) Python 代碼的 PEP 8 樣式規(guī)則,這是一種不好的做法

          賦值語句的使用消除了 lambda 表達(dá)式相對于顯式 def 語句所能提供的唯一好處(即,它可以嵌入到更大的表達(dá)式中)

          因此如果我們確實(shí)需要存儲一個(gè)函數(shù)以供進(jìn)一步使用,我們最好定義一個(gè)等效的普通函數(shù),而不是將 lambda 函數(shù)分配給變量

          Lambda 函數(shù)在 Python 中的應(yīng)用

          帶有 filter() 函數(shù)的 Lambda

          Python 中的 filter() 函數(shù)需要兩個(gè)參數(shù):

          • 定義過濾條件的函數(shù)
          • 函數(shù)在其上運(yùn)行的可迭代對象

          運(yùn)行該函數(shù),我們得到一個(gè)過濾器對象:

          lst = [333222111]
          filter(lambda x: x > 10, lst)

          Output:

          <filter at 0x250cb090520>

          為了從過濾器對象中獲取一個(gè)新的迭代器,并且原始迭代器中的所有項(xiàng)都滿足預(yù)定義的條件,我們需要將過濾器對象傳遞給 Python 標(biāo)準(zhǔn)庫的相應(yīng)函數(shù):list()、tuple()、set ()、frozenset() 或 sorted()(返回排序列表)

          讓我們過濾一個(gè)數(shù)字列表,只選擇大于 10 的數(shù)字并返回一個(gè)按升序排序的列表:

          lst = [333222111]
          sorted(filter(lambda x: x > 10, lst))

          Output:

          [11, 22, 33]

          我們不必創(chuàng)建與原始對象相同類型的新可迭代對象,此外我們可以將此操作的結(jié)果存儲在一個(gè)變量中:

          lst = [333222111]
          tpl = tuple(filter(lambda x: x > 10, lst))
          tpl

          Output:

          (33, 22, 11)

          帶有 map() 函數(shù)的 Lambda

          我們使用 Python 中的 map() 函數(shù)對可迭代的每個(gè)項(xiàng)目執(zhí)行特定操作。它的語法與 filter() 相同:一個(gè)要執(zhí)行的函數(shù)和一個(gè)該函數(shù)適用的可迭代對象。

          map() 函數(shù)返回一個(gè) map 對象,我們可以通過將該對象傳遞給相應(yīng)的 Python 函數(shù)來從中獲取一個(gè)新的迭代:list()、tuple()、set()、frozenset() 或 sorted()

          與 filter() 函數(shù)一樣,我們可以從 map 對象中提取與原始類型不同類型的可迭代對象,并將其分配給變量。

          下面是使用 map() 函數(shù)將列表中的每個(gè)項(xiàng)目乘以 10 并將映射值作為分配給變量 tpl 的元組輸出的示例:

          lst = [12345]
          print(map(lambda x: x * 10, lst))
          tpl = tuple(map(lambda x: x * 10, lst))
          tpl

          Output:

          <map object at 0x00000250CB0D5F40>

          (10, 20, 30, 40, 50)

          map() 和 filter() 函數(shù)之間的一個(gè)重要區(qū)別是第一個(gè)函數(shù)總是返回與原始函數(shù)相同長度的迭代。因此由于 pandas Series 對象也是可迭代的,我們可以在 DataFrame 列上應(yīng)用 map() 函數(shù)來創(chuàng)建一個(gè)新列:

          import pandas as pd
          df = pd.DataFrame({'col1': [12345], 'col2': [00000]})
          print(df)
          df['col3'] = df['col1'].map(lambda x: x * 10)
          df

          Output:

            col1  col2
          0 1 0
          1 2 0
          2 3 0
          3 4 0
          4 5 0

          col1 col2 col3
          0 1 0 10
          1 2 0 20
          2 3 0 30
          3 4 0 40
          4 5 0 50

          當(dāng)然要在上述情況下獲得相同的結(jié)果,也可以使用 apply() 函數(shù):

          df['col3'] = df['col1'].apply(lambda x: x * 10)
          df

          Output:

             col1  col2  col3
          0 1 0 10
          1 2 0 20
          2 3 0 30
          3 4 0 40
          4 5 0 50

          我們還可以根據(jù)某些條件為另一列創(chuàng)建一個(gè)新的 DataFrame 列,對于下面的代碼,我們可以互換使用 map() 或 apply() 函數(shù):

          df['col4'] = df['col3'].map(lambda x: 30 if x < 30 else x)
          df

          Output:

             col1  col2  col3  col4
          0 1 0 10 30
          1 2 0 20 30
          2 3 0 30 30
          3 4 0 40 40
          4 5 0 50 50

          帶有 reduce() 函數(shù)的 Lambda

          reduce() 函數(shù)與 functools Python 模塊相關(guān),它的工作方式如下:

          • 對可迭代對象的前兩項(xiàng)進(jìn)行操作并保存結(jié)果
          • 對保存的結(jié)果和可迭代的下一項(xiàng)進(jìn)行操作
          • 以這種方式在值對上進(jìn)行,直到所有項(xiàng)目使用可迭代的

          該函數(shù)與前兩個(gè)函數(shù)具有相同的兩個(gè)參數(shù):一個(gè)函數(shù)和一個(gè)可迭代對象。但是與前面的函數(shù)不同的是,這個(gè)函數(shù)不需要傳遞給任何其他函數(shù),直接返回結(jié)果標(biāo)量值:

          from functools import reduce
          lst = [12345]
          reduce(lambda x, y: x + y, lst)

          Output:

          15

          上面的代碼展示了我們使用 reduce() 函數(shù)計(jì)算列表總和時(shí)的作用

          需要注意的是,reduce() 函數(shù)總是需要一個(gè)帶有兩個(gè)參數(shù)的 lambda 函數(shù),而且我們必須首先從 functools Python 模塊中導(dǎo)入它

          Python 中 Lambda 函數(shù)的優(yōu)缺點(diǎn)

          優(yōu)點(diǎn)

          • 它是評估單個(gè)表達(dá)式的理想選擇,應(yīng)該只評估一次
          • 它可以在定義后立即調(diào)用
          • 與相應(yīng)的普通語法相比,它的語法更緊湊
          • 它可以作為參數(shù)傳遞給高階函數(shù),例如 filter()、map() 和 reduce()

          缺點(diǎn)

          • 它不能執(zhí)行多個(gè)表達(dá)式
          • 它很容易變得麻煩,可讀性差,例如當(dāng)它包括一個(gè) if-elif-...-else 循環(huán)
          • 它不能包含任何變量賦值(例如,lambda x: x=0 將拋出一個(gè)語法錯(cuò)誤)
          • 我們不能為 lambda 函數(shù)提供文檔字符串

          總結(jié)

          總而言之,我們已經(jīng)詳細(xì)討論了在 Python 中定義和使用 lambda 函數(shù)的許多方面:

          • lambda 函數(shù)與普通 Python 函數(shù)有何不同
          • Python 中 lambda 函數(shù)的語法和剖析
          • 何時(shí)使用 lambda 函數(shù)
          • lambda 函數(shù)的工作原理
          • 如何調(diào)用 lambda 函數(shù)
          • 調(diào)用函數(shù)執(zhí)行(IIFE)的定義
          • 如何使用 lambda 函數(shù)執(zhí)行條件操作,如何嵌套多個(gè)條件,以及為什么我們應(yīng)該避免它
          • 為什么我們應(yīng)該避免將 lambda 函數(shù)分配給變量
          • 如何將 lambda 函數(shù)與 filter() 函數(shù)一起使用
          • 如何將 lambda 函數(shù)與 map() 函數(shù)一起使用
          • 我們?nèi)绾卧?pandas DataFrame 中使用
          • 帶有傳遞給它的 lambda 函數(shù)的 map() 函數(shù) - 以及在這種情況下使用的替代功能
          • 如何將 lambda 函數(shù)與 reduce() 函數(shù)一起使用
          • 在普通 Python 上使用 lambda 函數(shù)的優(yōu)缺點(diǎn)


          希望今天的討論可以使 Python 中看似令人生畏的 lambda 函數(shù)概念更清晰、更易于應(yīng)用,更希望小伙伴們能夠喜歡,喜歡就點(diǎn)個(gè)吧!




          推薦閱讀:

          入門: 最全的零基礎(chǔ)學(xué)Python的問題  | 零基礎(chǔ)學(xué)了8個(gè)月的Python  | 實(shí)戰(zhàn)項(xiàng)目 |學(xué)Python就是這條捷徑


          干貨:爬取豆瓣短評,電影《后來的我們》 | 38年NBA最佳球員分析 |   從萬眾期待到口碑撲街!唐探3令人失望  | 笑看新倚天屠龍記 | 燈謎答題王 |用Python做個(gè)海量小姐姐素描圖 |碟中諜這么火,我用機(jī)器學(xué)習(xí)做個(gè)迷你推薦系統(tǒng)電影


          趣味:彈球游戲  | 九宮格  | 漂亮的花 | 兩百行Python《天天酷跑》游戲!


          AI: 會做詩的機(jī)器人 | 給圖片上色 | 預(yù)測收入 | 碟中諜這么火,我用機(jī)器學(xué)習(xí)做個(gè)迷你推薦系統(tǒng)電影


          小工具: Pdf轉(zhuǎn)Word,輕松搞定表格和水??! | 一鍵把html網(wǎng)頁保存為pdf!|  再見PDF提取收費(fèi)! | 用90行代碼打造最強(qiáng)PDF轉(zhuǎn)換器,word、PPT、excel、markdown、html一鍵轉(zhuǎn)換 | 制作一款釘釘?shù)蛢r(jià)機(jī)票提示器! |60行代碼做了一個(gè)語音壁紙切換器天天看小姐姐!



          年度爆款文案

          點(diǎn)閱讀原文,看B站我的視頻!

          瀏覽 50
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

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

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  激情婷婷开心五月丁香 | 手机看片自拍自拍自拍日轉 | 91干色 | 欧美在线日韩在线 | 91五月丁香啪啪视频 |