【一不小心就學會Python Lambda匿名函數的3個要點】

更新 發佈閱讀 12 分鐘

你會在程式裡面寫函數嗎?

通常寫函數的第一個問題,就是要給函數取名字。

名字取得不好,後來調用函數不自然,就會拖垮整個寫程式的效率。

為函數命名,也是一門技術,好的函數命名,就能提高函數被重複使用的頻率。

然而,也是在某些情況下,我們需要「一次性函數」。

沒錯,用完即丟的函數。

這時候就需要Lambda。

raw-image

學習Lambda是一件其實不會太困難的事情,具體你可以往這三個方面學習:

▋1. lambda是一種回傳數據特定形式的匿名函數。

▋2. 定義一個lambda需要指定參數(Parameters)與表達(Expression)

▋3. lambda的關鍵用法,是在將一個函數作為參數輸入另一個函數,也就是執行泛函操作

而這是我理解這3個方面的方式:

❏ lambda是一種回傳數據特定形式的匿名函數。

lambda 是所謂的「匿名函數 (Anonymous Function)」。

根據維基百科,「匿名函數」是一種不需要與識別符(Identifier)作綁定(Bound)的函數。^[an anonymous function (function literal, lambda abstraction, lambda function, lambda expression or block) is a function definition that is not bound to an identifier.]

這裡的識別符,就是函數的名字;而綁定就是將函數匹配到名字的字串上。

透過 lambda,我們可以省下命名一個函數的工,然後把lambda運算完的結果,儲存到另一個變數中。

這樣的過程十分管用,尤其是在想要對向量或者字典做高階函數運算的時候。

案例一:使用 map 來對列表的每一個元素進行平方運算。

要將每個元素平方,但其實不用再額外寫一個「平方函數」,透過lambda,直接用map就可以作用。

squared = map(lambda x: x**2, [1, 2, 3, 4])
print(list(squared)) # 輸出會是 [1, 4, 9, 16]

案例二:使用 filter 來過濾出列表中大於 10 的元素。

要比大小,直觀事先對每個元素比大小,把比大小結果的1與0翻譯回來。但透過lambda,可以省去for迴圈以及比大小的過程。

filtered = filter(lambda x: x > 10, [5, 11, 3, 12])
print(list(filtered)) # 輸出會是 [11, 12]

案例三:使用sorted 來依照特定規則排序一個元組列表。

要給元組排序是一件苦差事,你要先指定維度,然後在一個一個去比。但透過lambda,可以直接搭配sorted來拿到結果,不用額外寫一個函數去一個一個比。

pairs = [(1, 'one'), (4, 'four'), (3, 'three'), (2, 'two')]
sorted_pairs = sorted(pairs, key=lambda x: x[1])
print(sorted_pairs) # 輸出會是 [(4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')]

原則上,掌握lambda,你可以寫出更簡潔的Python code,也可以提高可用性。lambda尤其是在處理trivial的運算特別好用!

❏ 定義一個lambda需要指定參數(Parameters)與表達(Expression)

要創造lambda,其語法是

lambda parameters:expression

其中

  • 參數 (Parameters):是lambda函數要操作的數據
  • 表達(Expression):是lambda函數要返還的數據

會寫lambda非常有用,可以客製化很多簡單的運算。

例子一:乘法

multiply = lambda x, y: x * y
print(multiply(5, 3)) # Output: 15

例子二:最大值

maximum = lambda x, y: x if x > y else y
print(maximum(5, 8)) # Output: 8

例子三:反轉布林值

negate = lambda x: not x
print(negate(True)) # Output: False
print(negate(False)) # Output: True

例子四:字符串拼接

concatenate = lambda str1, str2: str1 + str2
print(concatenate("Hello, ", "world!")) # Output: Hello, world!

例子五:串連三個字串的第一個元素

concat_strings = lambda a, b, c: a[0] + b[0] + c[0] 
print(concat_strings("World", "Wide", "Web"))

例子六:拿列表的第一個元素

first_element = lambda x: x[0] if len(x) > 0 else "List is empty"
print(first_element([1, 2, 3])) # Output: 1
print(first_element([])) # Output: List is empty

妥善去使用lambda,甚至可以把程式代碼變得更加口語化,讓各種抽象的操作變得更加簡潔,非常值得學習。

❏ lambda的關鍵用法,是在將一個函數作為參數輸入另一個函數,也就是執行泛函操作

泛函(Functional)是一種以「函數」為定義域的映射。

也就是說,每一個泛函要運算時,都要輸入一個函數作為參數,然後輸出我們需要的資訊。

例子一:樣本變異

舉一個統計中常見的例子,是計算「樣本變異 (Sample Variance)」。

將計算樣本變異看為泛函操作,那所需要輸入的函數其實是「取平均後開根號」,因為樣本變異是平均數(平均值)周圍數據點變動的一種度量。簡單來說,樣本變異是數據點與平均值的差值平方的平均。在這個情境下,"取平均後開根號" 的函數可以被看作是一個泛函的參數。

如果將這個操作使用 Python 來實現,我們可以用 lambda 函數來表達:

# 一個簡單的平均數函數
average = lambda arr: sum(arr) / len(arr)

# 樣本變異的泛函
def sample_variance_functional(f, data):
mean = f(data) # 使用輸入的函數計算平均數
return sum((x - mean)**2 for x in data) / (len(data) - 1)

# 使用泛函計算樣本變異
data = [1, 2, 3, 4, 5]
result = sample_variance_functional(average, data)
print("Sample Variance:", result)

在這個例子中,sample_variance_functional 是一個泛函,它接受一個函數 f 和一個數據集 data,然後計算該數據集的樣本變異。這個泛函使用了輸入的函數 f(在這裡是 average)來計算數據集的平均數,然後用這個平均數去計算樣本變異。

這個例子展示了 lambda 函數和泛函的概念是如何結合在一起的。通過這種方式,我們可以將各種不同的函數(比如加權平均,中位數等)作為 sample_variance_functional 的參數,來計算相對應的樣本變異。

這提供了高度的靈活性和可擴展性。我們可以把輸入的函數f替換成其他的函數,可以是weighted_average或者是其他形式的平均,如此來討論更廣義的「變異數 (Variance)」觀念。

例子二:得到一組數字的平方根

假設我們有一個數組,我們想對這個數組的每一個元素取平方根。我們可以定義一個泛函,這個泛函接受一個函數(這裡是取平方根的函數)和一個數組,然後返回一個新的數組。

import math

# 定義一個泛函,這個泛函接受一個函數 f 和一個列表 lst
def map_functional(f, lst):
return list(map(f, lst))

# 使用 lambda 函數定義取平方根的操作
sqrt_function = lambda x: math.sqrt(x)

# 定義一個數組
numbers = [1, 4, 9, 16, 25]

# 使用泛函計算數組的平方根
sqrt_numbers = map_functional(sqrt_function, numbers)
print("Square roots:", sqrt_numbers)

在這個例子中,map_functional 是一個泛函,它接受一個函數 f 和一個列表 lst。這個泛函用 map 函數來對列表 lst 的每一個元素應用函數 f,然後返回一個新的列表。

這樣,我們就可以使用不同的函數(不只是取平方根)來轉換 numbers 列表。這提供了高度的靈活性,允許我們輕鬆地替換處理數據的邏輯。

例子三:過濾出偶數

我們可以使用 filterlambda 函數來過濾一個列表中的元素。這裡的例子是一個泛函,它接受一個判斷函數(predicate function)和一個列表,然後返回一個只包含符合條件的元素的新列表。

# 定義一個泛函,這個泛函接受一個函數 f 和一個列表 lst
def filter_functional(f, lst):
return list(filter(f, lst))

# 使用 lambda 函數定義一個判斷是否為偶數的函數
is_even = lambda x: x % 2 == 0

# 定義一個整數列表
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# 使用泛函過濾出偶數
even_numbers = filter_functional(is_even, numbers)
print("Even numbers:", even_numbers)

在這個例子中,filter_functional 是一個泛函,它接受一個函數 f 和一個列表 lst。然後它用 filter 函數來過濾出列表 lst 中符合函數 f 條件的元素。

這樣,我們就可以使用不同的判斷函數來過濾 numbers 列表,這提供了很高的靈活性。例如,我們可以簡單地更換 lambda 函數,以過濾出大於 5 的所有數字,或者能被 3 整除的數字等等。

如此,只要能活用lambda,搭配上泛函的框架,就能操作各式各樣稍微複雜的數學操作!掌握lambda思維,就能掌握計算數學的能力!

▋寫在最後

學習如何正確地使用 lambda 函數和泛函是一個值得投資的時間和努力的過程。他們不僅可以幫助你寫出更簡潔、更高效的程式碼,而且也能提供更高的靈活性和可擴展性。

通過這篇文章,我們探討了以下三個方面:

  1. lambda 是一種特定形式的匿名函數,它可以讓我們快速地定義簡單的一次性函數。
  2. lambda 函數的定義需要指定參數和表達式,這讓我們能夠根據需要自定義各種運算。
  3. lambda 函數與泛函的組合使用可以讓我們以一種更抽象和通用的方式來處理問題。

透過實例和代碼,你也看到了這些與lambda相關的概念是如何具體應用的。希望這能幫助你更好地理解和使用 lambda 函數,並在你的程式設計之旅中找到它們的價值!

留言
avatar-img
王啟樺的沙龍
650會員
2.0K內容數
Outline as Content
王啟樺的沙龍的其他內容
2025/03/29
Passive Consumption(被動接收) vs. Active Reading(主動閱讀)|真正讓你進化的閱讀差在這裡 碩博士生每天都在讀論文、讀報告、讀教材, 但大多數人其實只是「看過了」,不是「讀進去了」。 讀很多卻吸收很少,記不起重點、寫不出心得, 不是你不夠努力,而是你還停
2025/03/29
Passive Consumption(被動接收) vs. Active Reading(主動閱讀)|真正讓你進化的閱讀差在這裡 碩博士生每天都在讀論文、讀報告、讀教材, 但大多數人其實只是「看過了」,不是「讀進去了」。 讀很多卻吸收很少,記不起重點、寫不出心得, 不是你不夠努力,而是你還停
2025/01/29
4 個關鍵洞見 + 讓你看懂中美 AI 競爭 + 若不讀,你就可能錯失整個時代的最大機遇 AI 的發展速度,真的快到讓人心驚。 我們常常以為美國在 AI 領域穩居頂尖,可現在中國的 AI 創新力好像開始迎頭趕上,這背後的原因是什麼? 若我們沒有跟上這波 AI 變革,就可能被遠遠拋在後面,錯失技
Thumbnail
2025/01/29
4 個關鍵洞見 + 讓你看懂中美 AI 競爭 + 若不讀,你就可能錯失整個時代的最大機遇 AI 的發展速度,真的快到讓人心驚。 我們常常以為美國在 AI 領域穩居頂尖,可現在中國的 AI 創新力好像開始迎頭趕上,這背後的原因是什麼? 若我們沒有跟上這波 AI 變革,就可能被遠遠拋在後面,錯失技
Thumbnail
看更多
你可能也想看
Thumbnail
vocus 慶祝推出 App,舉辦 2026 全站慶。推出精選內容與數位商品折扣,訂單免費與紅包抽獎、新註冊會員專屬活動、Boba Boost 贊助抽紅包,以及全站徵文,並邀請你一起來回顧過去的一年, vocus 與創作者共同留下了哪些精彩創作。
Thumbnail
vocus 慶祝推出 App,舉辦 2026 全站慶。推出精選內容與數位商品折扣,訂單免費與紅包抽獎、新註冊會員專屬活動、Boba Boost 贊助抽紅包,以及全站徵文,並邀請你一起來回顧過去的一年, vocus 與創作者共同留下了哪些精彩創作。
Thumbnail
這一篇會介紹非常重要的 JavaScript 函式概念 - 高階函式(Higher-order function),高階函數是將一個或多個函數作為參數,或將一個函數作為結果返回的函數。在本文中,我們將深入探討什麽是高階函數、使用高階函數的好處以及如何在實際應用中使用高階函數,函式導向是什麼?
Thumbnail
這一篇會介紹非常重要的 JavaScript 函式概念 - 高階函式(Higher-order function),高階函數是將一個或多個函數作為參數,或將一個函數作為結果返回的函數。在本文中,我們將深入探討什麽是高階函數、使用高階函數的好處以及如何在實際應用中使用高階函數,函式導向是什麼?
Thumbnail
你會在程式裡面寫函數嗎? 通常寫函數的第一個問題,就是要給函數取名字。 名字取得不好,後來調用函數不自然,就會拖垮整個寫程式的效率。 為函數命名,也是一門技術,好的函數命名,就能提高函數被重複使用的頻率。 然而,也是在某些情況下,我們需要「一次性函數」。 沒錯,用完即丟的函數。
Thumbnail
你會在程式裡面寫函數嗎? 通常寫函數的第一個問題,就是要給函數取名字。 名字取得不好,後來調用函數不自然,就會拖垮整個寫程式的效率。 為函數命名,也是一門技術,好的函數命名,就能提高函數被重複使用的頻率。 然而,也是在某些情況下,我們需要「一次性函數」。 沒錯,用完即丟的函數。
Thumbnail
👨‍💻簡介 在 Golang 中,你可以使用不同的方式來宣告變數和常數。宣告變數時,可以直接指定值,或者使用型別推導,更簡單地用 := 來宣告局部變數。另外,還可以一次宣告多個變數,相同型別的變數可以一起宣告,或者使用括號宣告不同型別的變數。常數則使用 const 關鍵字宣告,確保值不變
Thumbnail
👨‍💻簡介 在 Golang 中,你可以使用不同的方式來宣告變數和常數。宣告變數時,可以直接指定值,或者使用型別推導,更簡單地用 := 來宣告局部變數。另外,還可以一次宣告多個變數,相同型別的變數可以一起宣告,或者使用括號宣告不同型別的變數。常數則使用 const 關鍵字宣告,確保值不變
Thumbnail
這篇文章將會介紹函式(Function)及其回傳值(retrun)的定義及介紹。
Thumbnail
這篇文章將會介紹函式(Function)及其回傳值(retrun)的定義及介紹。
Thumbnail
雜湊演算法(hash function)。或許你聽過它,但你是否了解它?劍術大師都說要人劍合一了,若是資訊人員不能人與技術合一,那要如何登峰造極?我們必須正確的使用它,才能讓它變成你的武器。 縮圖來源:https://www.pexels.com/zh-tw/photo/53207/
Thumbnail
雜湊演算法(hash function)。或許你聽過它,但你是否了解它?劍術大師都說要人劍合一了,若是資訊人員不能人與技術合一,那要如何登峰造極?我們必須正確的使用它,才能讓它變成你的武器。 縮圖來源:https://www.pexels.com/zh-tw/photo/53207/
Thumbnail
函式(Function)、傳值法、傳位址法、傳參考法
Thumbnail
函式(Function)、傳值法、傳位址法、傳參考法
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News