【一不小心就學會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 函數,並在你的程式設計之旅中找到它們的價值!

371會員
1.2K內容數
Outline as Content
留言0
查看全部
發表第一個留言支持創作者!
王啟樺的沙龍 的其他內容
你會怎麼將Atlas翻譯成中文呢? Atlas (阿特拉斯)是希臘神話中掌管耐力,力量與天文的泰坦神。在地球上,大西洋就是阿特拉斯之海,而亞特蘭提斯則是阿特拉斯之島。 Atlas在中文的翻譯是「輿圖」,在牛津字典的定義是「地圖冊 (a book of maps)」。
對於網路寫作者、部落格主或是內容創作者而言,這篇文章或許是你需要的。 系列文創作不僅解決了「單篇文章缺乏深度」的問題,還能有效提升網站或個人品牌的流量。 這是我在實踐「系列文創作」之後,獲得的三大體悟。
他們可以解決我們如何有效地捕捉與管理我們的思考。我們可以透過他們的使用,提升我們的知識生產力,進一步豐富我們的思考與認知。當你一直在學習,一直在思考,這就是你需要的工具。
對於那些希望提升創作力的人來說,這篇文章將會是你的指南!
ACE 框架是 Nick Milo 在2023年8月中發表,即將在Linking Your Thinking Workshop 12重點討論的知識管理框架。 ACE 分別代表著Atlas (輿圖),Calendar(曆法)與Efforts(奮鬥)三個元素。
隨著時間的推移,我們的筆記方法可能會改變。 不論是筆記的內容還是方法,都需要隨著學習的深入而進行調整。 持續的反思和嘗試是筆記進步的關鍵。 ▋我們的筆記方法為何會隨著時間而改變? 因為你寫筆記的目的也會換。
你會怎麼將Atlas翻譯成中文呢? Atlas (阿特拉斯)是希臘神話中掌管耐力,力量與天文的泰坦神。在地球上,大西洋就是阿特拉斯之海,而亞特蘭提斯則是阿特拉斯之島。 Atlas在中文的翻譯是「輿圖」,在牛津字典的定義是「地圖冊 (a book of maps)」。
對於網路寫作者、部落格主或是內容創作者而言,這篇文章或許是你需要的。 系列文創作不僅解決了「單篇文章缺乏深度」的問題,還能有效提升網站或個人品牌的流量。 這是我在實踐「系列文創作」之後,獲得的三大體悟。
他們可以解決我們如何有效地捕捉與管理我們的思考。我們可以透過他們的使用,提升我們的知識生產力,進一步豐富我們的思考與認知。當你一直在學習,一直在思考,這就是你需要的工具。
對於那些希望提升創作力的人來說,這篇文章將會是你的指南!
ACE 框架是 Nick Milo 在2023年8月中發表,即將在Linking Your Thinking Workshop 12重點討論的知識管理框架。 ACE 分別代表著Atlas (輿圖),Calendar(曆法)與Efforts(奮鬥)三個元素。
隨著時間的推移,我們的筆記方法可能會改變。 不論是筆記的內容還是方法,都需要隨著學習的深入而進行調整。 持續的反思和嘗試是筆記進步的關鍵。 ▋我們的筆記方法為何會隨著時間而改變? 因為你寫筆記的目的也會換。
你可能也想看
Google News 追蹤
Thumbnail
本專欄將提供給您最新的市場資訊、產業研究、交易心法、精選公司介紹,以上內容並非個股分析,還請各位依據自身狀況作出交易決策。歡迎訂閱支持我,獲得相關內容,也祝您的投資之路順遂! 每年 $990 訂閱方案👉 https://reurl.cc/VNYVxZ 每月 $99 訂閱方案👉https://re
1. 體驗前後的差異: - 「學習,一言以蔽之,就是‘體驗前與體驗後的差異’。」這句話出自日本作者荒木博行與海老澤潮的著書《独学の地図》中的第58頁。他們認為,體驗某件事以前的你,與體驗某件事後的你之間的差異,就是學習。這種透過「體驗前後的差異」來定義「學習」的角度相當新穎。 2. 將日
Thumbnail
說到羅東,大家第一印象想到的應該都是山青水秀、空氣清新,當然確實也如此。然而對於我來說,羅東給我的印象卻更多是好吃便宜的東西很多,而且有些餐點一開始都以為是小小份的,買了之後痛並快樂著——好吃但又吃到很撐,滿滿都是一不小心買太多、吃太多的回憶XD
Thumbnail
1.職場中,每個年度各部門都會有不同的目標需要設定與達成,目標設定太大覺得空泛,設定太小又沒有挑戰。 2.目標的執行可以分成能力與意願,即會不會做和想不想做,適時激發提升同仁對目標的意義感對達標有莫大的幫助
Thumbnail
推薦書籍到現在,還是會收到不少人表示一看到某些書的厚度就先望之卻步,雖然書的厚薄對我來說一直都不是重點,能不能引人入勝才是關鍵。況且厚的書也有可能內容摻水,薄的書有時字字珠璣,讀來暢快。儘管如此,若你對厚度仍有一定程度的在意,這次乾脆集結近日看完,薄度都剛好在兩百頁內又值得推薦的書!
Thumbnail
你會在程式裡面寫函數嗎? 通常寫函數的第一個問題,就是要給函數取名字。 名字取得不好,後來調用函數不自然,就會拖垮整個寫程式的效率。 為函數命名,也是一門技術,好的函數命名,就能提高函數被重複使用的頻率。 然而,也是在某些情況下,我們需要「一次性函數」。 沒錯,用完即丟的函數。
Thumbnail
一位男子不小心將500元的加值電話費加到了一位老婆婆的號碼上,隨後男子打電話給老婆婆,請求將錢退回來。老婆婆要求男子明天帶上身分證和戶口名簿來拿錢。男子覺得很奇怪,但最終遵從老婆婆的要求,拿回了錢。老婆婆表示需要一位司機,邀請男子留下來擔任司機,男子最終留了下來,陪伴老婆婆15年,直到老婆婆去世。
Thumbnail
昨天晚上和苟維斯終於把放在冰箱一個多禮拜的芭樂切來吃,下班後的我們都又累又懶惰,忘了吃水果是很常見的事。 苟維斯做事又快又隨便,切好的芭樂上面還有幾絲沒剝乾淨的黑色鬚鬚。 「為什麼芭樂都有一撮黑黑的毛?」不等苟維斯回答,我邊問邊拿起手機問google。
Thumbnail
據說一個月不發文,狀態就會想顯現成「魔法師」。
Thumbnail
多謝這年陪我走過的朋友。 '要記得嗰啲大雨中為你撐傘嘅人,幫你擋住外來之物嘅人…陪你徹夜聊天嘅人…陪你哭過嘅人…帶住你四處遊盪嘅人…組成你生命中一點一滴嘅溫暖…' 《天各一方》旁白
Thumbnail
本專欄將提供給您最新的市場資訊、產業研究、交易心法、精選公司介紹,以上內容並非個股分析,還請各位依據自身狀況作出交易決策。歡迎訂閱支持我,獲得相關內容,也祝您的投資之路順遂! 每年 $990 訂閱方案👉 https://reurl.cc/VNYVxZ 每月 $99 訂閱方案👉https://re
1. 體驗前後的差異: - 「學習,一言以蔽之,就是‘體驗前與體驗後的差異’。」這句話出自日本作者荒木博行與海老澤潮的著書《独学の地図》中的第58頁。他們認為,體驗某件事以前的你,與體驗某件事後的你之間的差異,就是學習。這種透過「體驗前後的差異」來定義「學習」的角度相當新穎。 2. 將日
Thumbnail
說到羅東,大家第一印象想到的應該都是山青水秀、空氣清新,當然確實也如此。然而對於我來說,羅東給我的印象卻更多是好吃便宜的東西很多,而且有些餐點一開始都以為是小小份的,買了之後痛並快樂著——好吃但又吃到很撐,滿滿都是一不小心買太多、吃太多的回憶XD
Thumbnail
1.職場中,每個年度各部門都會有不同的目標需要設定與達成,目標設定太大覺得空泛,設定太小又沒有挑戰。 2.目標的執行可以分成能力與意願,即會不會做和想不想做,適時激發提升同仁對目標的意義感對達標有莫大的幫助
Thumbnail
推薦書籍到現在,還是會收到不少人表示一看到某些書的厚度就先望之卻步,雖然書的厚薄對我來說一直都不是重點,能不能引人入勝才是關鍵。況且厚的書也有可能內容摻水,薄的書有時字字珠璣,讀來暢快。儘管如此,若你對厚度仍有一定程度的在意,這次乾脆集結近日看完,薄度都剛好在兩百頁內又值得推薦的書!
Thumbnail
你會在程式裡面寫函數嗎? 通常寫函數的第一個問題,就是要給函數取名字。 名字取得不好,後來調用函數不自然,就會拖垮整個寫程式的效率。 為函數命名,也是一門技術,好的函數命名,就能提高函數被重複使用的頻率。 然而,也是在某些情況下,我們需要「一次性函數」。 沒錯,用完即丟的函數。
Thumbnail
一位男子不小心將500元的加值電話費加到了一位老婆婆的號碼上,隨後男子打電話給老婆婆,請求將錢退回來。老婆婆要求男子明天帶上身分證和戶口名簿來拿錢。男子覺得很奇怪,但最終遵從老婆婆的要求,拿回了錢。老婆婆表示需要一位司機,邀請男子留下來擔任司機,男子最終留了下來,陪伴老婆婆15年,直到老婆婆去世。
Thumbnail
昨天晚上和苟維斯終於把放在冰箱一個多禮拜的芭樂切來吃,下班後的我們都又累又懶惰,忘了吃水果是很常見的事。 苟維斯做事又快又隨便,切好的芭樂上面還有幾絲沒剝乾淨的黑色鬚鬚。 「為什麼芭樂都有一撮黑黑的毛?」不等苟維斯回答,我邊問邊拿起手機問google。
Thumbnail
據說一個月不發文,狀態就會想顯現成「魔法師」。
Thumbnail
多謝這年陪我走過的朋友。 '要記得嗰啲大雨中為你撐傘嘅人,幫你擋住外來之物嘅人…陪你徹夜聊天嘅人…陪你哭過嘅人…帶住你四處遊盪嘅人…組成你生命中一點一滴嘅溫暖…' 《天各一方》旁白