<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
今天我們來學習 Python 中的 lambda 函數,並探討使用它的優點和侷限性
Let's do it!
lambda 函數是一個匿名函數(即,沒有名稱定義),它可以接受任意數量的引數,但與普通函數不同,它只計算並返回一個表示式
Python 中的 lambda 函數使用以下語法表達:
lambda 引數:表示式
lambda 函數包括三個元素:
需要注意的是,普通函數不同,這裡不需要用括號將 lambda 函數的引數括起來,如果 lambda 函數有兩個或更多引數,我們用逗號列出它們
我們使用 lambda 函數只計算一個短表示式(理想情況下,單行)並且只計算一次,這意味著我們以後不會再複用這個函數。 通常來說我們會將 lambda 函數作為引數傳遞給高階函數(接受其他函數作為引數的函數),例如 Python 內建函數,如 filter()、map() 或 reduce()等
讓我們看一個簡單的 lambda 函數範例:
lambda x: x + 1
Output:
<function __main__.<lambda>(x)>
上面的 lambda 函數接受一個引數,將其遞增 1,然後返回結果
它是以下帶有 def 和 return 關鍵字的普通函數的更簡單版本:
def increment_by_one(x): return x + 1
到目前我們的 lambda 函數 lambda x: x + 1
只建立一個函數物件,不返回任何內容,這是因為我們沒有為其引數 x 提供任何值(引數)。讓我們先分配一個變數,將它傳遞給 lambda 函數,看看這次我們得到了什麼:
a = 2 print(lambda x: a + 1)
Output:
<function <lambda> at 0x00000250CB0A5820>
我們的 lambda 函數沒有像我們預期的那樣返回 3,而是返回了函數物件本身及其記憶體位置,可以看出這不是呼叫 lambda 函數的正確方法。要將引數傳遞給 lambda 函數,執行它並返回結果,我們應該使用以下語法:
(lambda x: x + 1)(2)
Output:
3
雖然我們的 lambda 函數的引數沒有用括號括起來,但當我們呼叫它時,我們會在 lambda 函數的整個構造以及我們傳遞給它的引數週圍新增括號
上面程式碼中要注意的另一件事是,使用 lambda 函數,我們可以在建立函數後立即執行該函數並接收結果。這就是所謂的立即呼叫函數執行(或 IIFE)
我們可以建立一個帶有多個引數的 lambda 函數,在這種情況下,我們用逗號分隔函數定義中的引數。當我們執行這樣一個 lambda 函數時,我們以相同的順序列出相應的引數,並用逗號分隔它們:
(lambda x, y, z: x + y + z)(3, 8, 1)
Output:
12
也可以使用 lambda 函數來執行條件操作。下面是一個簡單 if-else 函數的 lambda 模擬:
print((lambda x: x if(x > 10) else 10)(5)) print((lambda x: x if(x > 10) else 10)(12))
Output:
10
12
如果存在多個條件(if-elif-...-else),我們必須巢狀它們:
(lambda x: x * 10 if x > 10 else (x * 5 if x < 5 else x))(11)
Output:
110
但是上面的寫法,又令程式碼變得難以閱讀
在這種情況下,具有 if-elif-...-else 條件集的普通函數將是比 lambda 函數更好的選擇。實際上,我們可以通過以下方式編寫上面範例中的 lambda 函數:
def check_conditions(x): if x > 10: return x * 10 elif x < 5: return x * 5 else: return x check_conditions(11)
Output:
110
儘管上面的函數比相應的 lambda 函數增加了更多行,但它更容易閱讀
我們可以將 lambda 函數分配給一個變數,然後將該變數作為普通函數呼叫:
increment = lambda x: x + 1 increment(2)
Output:
3
但是根據 Python 程式碼的 PEP 8 樣式規則,這是一種不好的做法
賦值語句的使用消除了 lambda 表示式相對於顯式 def 語句所能提供的唯一好處(即,它可以嵌入到更大的表示式中)
因此如果我們確實需要儲存一個函數以供進一步使用,我們最好定義一個等效的普通函數,而不是將 lambda 函數分配給變數
Python 中的 filter() 函數需要兩個引數:
執行該函數,我們得到一個過濾器物件:
lst = [33, 3, 22, 2, 11, 1] filter(lambda x: x > 10, lst)
Output:
<filter at 0x250cb090520>
為了從過濾器物件中獲取一個新的迭代器,並且原始迭代器中的所有項都滿足預定義的條件,我們需要將過濾器物件傳遞給 Python 標準庫的相應函數:list()、tuple()、set ()、frozenset() 或 sorted()(返回排序列表)
讓我們過濾一個數位列表,只選擇大於 10 的數位並返回一個按升序排序的列表:
lst = [33, 3, 22, 2, 11, 1] sorted(filter(lambda x: x > 10, lst))
Output:
[11, 22, 33]
我們不必建立與原始物件相同型別的新可迭代物件,此外我們可以將此操作的結果儲存在一個變數中:
lst = [33, 3, 22, 2, 11, 1] tpl = tuple(filter(lambda x: x > 10, lst)) tpl
Output:
(33, 22, 11)
我們使用 Python 中的 map() 函數對可迭代的每個專案執行特定操作。它的語法與 filter() 相同:一個要執行的函數和一個該函數適用的可迭代物件。
map() 函數返回一個 map 物件,我們可以通過將該物件傳遞給相應的 Python 函數來從中獲取一個新的迭代:list()、tuple()、set()、frozenset() 或 sorted()
與 filter() 函數一樣,我們可以從 map 物件中提取與原始型別不同型別的可迭代物件,並將其分配給變數。
下面是使用 map() 函數將列表中的每個專案乘以 10 並將對映值作為分配給變數 tpl 的元組輸出的範例:
lst = [1, 2, 3, 4, 5] 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() 函數之間的一個重要區別是第一個函數總是返回與原始函數相同長度的迭代。因此由於 pandas Series 物件也是可迭代的,我們可以在 DataFrame 列上應用 map() 函數來建立一個新列:
import pandas as pd df = pd.DataFrame({'col1': [1, 2, 3, 4, 5], 'col2': [0, 0, 0, 0, 0]}) 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
當然要在上述情況下獲得相同的結果,也可以使用 apply() 函數:
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
我們還可以根據某些條件為另一列建立一個新的 DataFrame 列,對於下面的程式碼,我們可以互換使用 map() 或 apply() 函數:
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() 函數與 functools Python 模組相關,它的工作方式如下:
該函數與前兩個函數具有相同的兩個引數:一個函數和一個可迭代物件。但是與前面的函數不同的是,這個函數不需要傳遞給任何其他函數,直接返回結果標量值:
from functools import reduce lst = [1, 2, 3, 4, 5] reduce(lambda x, y: x + y, lst)
Output:
15
上面的程式碼展示了我們使用 reduce() 函數計算列表總和時的作用
需要注意的是,reduce() 函數總是需要一個帶有兩個引數的 lambda 函數,而且我們必須首先從 functools Python 模組中匯入它
總而言之,我們已經詳細討論了在 Python 中定義和使用 lambda 函數的許多方面:
希望今天的討論可以使 Python 中看似令人生畏的 lambda 函數概念更清晰、更易於應用。
以上就是Python lambda 匿名函數優點和侷限性深度總結的詳細內容,更多關於Python lambda 匿名函數的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45