Python中常用最神秘的函數! lambda 函數深度總結!

WBOY
發布: 2023-04-12 23:13:09
轉載
1421 人瀏覽過

Python中常用最神秘的函數! lambda 函數深度總結!

什麼是Python 中的Lambda 函數

lambda 函數是一個匿名函數(即,沒有名稱定義),它可以接受任意數量的參數,但與普通函數不同,它只計算並傳回一個表達式。

Python 中的lambda 函數使用以下語法表達:

lambda 參數:表達式

lambda 函數包括三個元素:

  • #關鍵字lambda:與普通函數中def 類似
  • 參數:支援傳遞位置和關鍵字參數,與普通函數一樣
  • 正文:處理定參數的表達式

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

我們使用lambda函數只計算一個短表達式(理想情況下,單行)並且只計算一次,這意味著我們以後不會再重複使用這個函數。通常來說我們會將lambda 函數作為參數傳遞給高階函數(接受其他函數作為參數的函數),例如Python 內建函數,如filter()、map() 或reduce()等

Python中的Lambda 函數如何運作

讓我們看一個簡單的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 函數分配給變數

Lambda 函數在Python 中的應用

帶有filter() 函數的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)
登入後複製

带有 map() 函数的 Lambda

我们使用 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:

col1col2
0 1 0
1 2 0
2 3 0
3 4 0
4 5 0
col1col2col3
0 1 010
1 2 020
2 3 030
3 4 040
4 5 050
登入後複製

当然要在上述情况下获得相同的结果,也可以使用 apply() 函数:

df['col3'] = df['col1'].apply(lambda x: x * 10)
df
登入後複製

Output:

col1col2col3
0 1 010
1 2 020
2 3 030
3 4 040
4 5 050
登入後複製

我们还可以根据某些条件为另一列创建一个新的 DataFrame 列,对于下面的代码,我们可以互换使用 map() 或 apply() 函数:

df['col4'] = df['col3'].map(lambda x: 30 if x < 30 else x)
df
登入後複製

Output:

col1col2col3col4
0 1 01030
1 2 02030
2 3 03030
3 4 04040
4 5 05050
登入後複製

带有 reduce() 函数的 Lambda

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 函数的优缺点

优点

  • 评估单个表达式的理想选择,应该只评估一次
  • 它可以在定义后立即调用
  • 与相应的普通语法相比,它的语法更紧凑
  • 它可以作为参数传递给高阶函数,例如 filter()、map() 和 reduce()

缺点

  • 它不能执行多个表达式
  • 它很容易变得麻烦,可读性差,例如当它包括一个 if-elif-...-else 循环
  • 它不能包含任何变量赋值(例如,lambda x: x=0 将抛出一个语法错误)
  • 我们不能为 lambda 函数提供文档字符串

总结

总而言之,我们已经详细讨论了在 Python 中定义和使用 lambda 函数的许多方面:

  • lambda 函数与普通 Python 函数有何不同
  • Python 中 lambda 函数的语法和剖析
  • 何时使用 lambda 函数
  • lambda 函数的工作原理
  • 如何调用 lambda 函数
  • 调用函数执行(IIFE)的定义
  • 如何使用 lambda 函数执行条件操作,如何嵌套多个条件,以及为什么我们应该避免它
  • 为什么我们应该避免将 lambda 函数分配给变量
  • 如何将 lambda 函数与 filter() 函数一起使用
  • 如何将 lambda 函数与 map() 函数一起使用
  • 我们如何在 pandas DataFrame 中使用
  • 带有传递给它的 lambda 函数的 map() 函数 - 以及在这种情况下使用的替代功能
  • 如何将 lambda 函数与 reduce() 函数一起使用
  • 普通 Python 上使用 lambda 函数的优缺点

希望今天的讨论可以使 Python 中看似令人生畏的 lambda 函数概念更清晰、更易于应用,更希望小伙伴们能够喜欢,喜欢就点个赞吧!

以上是Python中常用最神秘的函數! lambda 函數深度總結!的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:51cto.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板