Python Lambda 匿名函數

Lambda 是一種簡潔的匿名函數寫法,用於建立小型的一次性函數。

基本語法

lambda 參數: 表達式
# 一般函數
def square(x):
    return x ** 2

# 等同的 lambda
square = lambda x: x ** 2

print(square(5))  # 25

Lambda 只能包含一個表達式,不能有多行語句或 return(表達式的結果就是回傳值)。

多個參數

add = lambda a, b: a + b
print(add(3, 5))  # 8

multiply = lambda x, y, z: x * y * z
print(multiply(2, 3, 4))  # 24

沒有參數

get_pi = lambda: 3.14159
print(get_pi())  # 3.14159

預設參數

greet = lambda name, greeting="Hello": f"{greeting}, {name}!"
print(greet("Alice"))            # Hello, Alice!
print(greet("Bob", "Hi"))        # Hi, Bob!

搭配內建函數使用

Lambda 最常見的用途是搭配需要函數參數的內建函數使用。

sorted() - 排序

# 按照字串長度排序
words = ["apple", "fig", "banana", "cherry"]
sorted_words = sorted(words, key=lambda x: len(x))
print(sorted_words)  # ['fig', 'apple', 'banana', 'cherry']

# 按照字典的某個欄位排序
users = [
    {"name": "Alice", "age": 25},
    {"name": "Bob", "age": 30},
    {"name": "Charlie", "age": 20}
]
sorted_users = sorted(users, key=lambda u: u["age"])
print(sorted_users)
# [{'name': 'Charlie', 'age': 20}, {'name': 'Alice', 'age': 25}, {'name': 'Bob', 'age': 30}]

# 降冪排序
sorted_users = sorted(users, key=lambda u: u["age"], reverse=True)

filter() - 過濾

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# 過濾出偶數
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(evens)  # [2, 4, 6, 8, 10]

# 過濾出大於 5 的數字
greater = list(filter(lambda x: x > 5, numbers))
print(greater)  # [6, 7, 8, 9, 10]

map() - 轉換

numbers = [1, 2, 3, 4, 5]

# 每個數字平方
squares = list(map(lambda x: x ** 2, numbers))
print(squares)  # [1, 4, 9, 16, 25]

# 轉換為字串
strings = list(map(lambda x: str(x), numbers))
print(strings)  # ['1', '2', '3', '4', '5']

reduce() - 累積

from functools import reduce

numbers = [1, 2, 3, 4, 5]

# 計算總和
total = reduce(lambda acc, x: acc + x, numbers)
print(total)  # 15

# 計算乘積
product = reduce(lambda acc, x: acc * x, numbers)
print(product)  # 120

# 找出最大值
max_num = reduce(lambda a, b: a if a > b else b, numbers)
print(max_num)  # 5

max() / min() - 自訂比較

# 找出最長的字串
words = ["apple", "fig", "banana"]
longest = max(words, key=lambda x: len(x))
print(longest)  # banana

# 找出年齡最大的人
users = [
    {"name": "Alice", "age": 25},
    {"name": "Bob", "age": 30}
]
oldest = max(users, key=lambda u: u["age"])
print(oldest["name"])  # Bob

條件表達式

Lambda 可以包含條件表達式(三元運算子):

# 判斷奇偶
check = lambda x: "even" if x % 2 == 0 else "odd"
print(check(4))  # even
print(check(5))  # odd

# 取絕對值
abs_val = lambda x: x if x >= 0 else -x
print(abs_val(-5))  # 5
print(abs_val(3))   # 3

Lambda vs 一般函數

何時使用 Lambda

  • 簡單的一次性操作
  • 作為函數參數(如 sortedfiltermap
  • 程式碼簡單到只需一行

何時使用一般函數

  • 需要多行程式碼
  • 需要文件字串 (docstring)
  • 會重複使用
  • 邏輯複雜需要可讀性
# 適合用 lambda
sorted(items, key=lambda x: x.name)

# 不適合用 lambda(太複雜)
# lambda x: x if x > 0 else (0 if x == 0 else -x)  # 難讀

# 改用一般函數
def sign(x):
    if x > 0:
        return 1
    elif x == 0:
        return 0
    else:
        return -1

實際範例

排序複雜資料

# 按多個條件排序
students = [
    {"name": "Alice", "grade": 85, "age": 20},
    {"name": "Bob", "grade": 90, "age": 22},
    {"name": "Charlie", "grade": 85, "age": 21}
]

# 先按成績降冪,成績相同按年齡升冪
sorted_students = sorted(
    students,
    key=lambda s: (-s["grade"], s["age"])
)
for s in sorted_students:
    print(s)

處理字串

# 移除字串前後空白並轉小寫
names = ["  Alice  ", "BOB", " Charlie"]
cleaned = list(map(lambda s: s.strip().lower(), names))
print(cleaned)  # ['alice', 'bob', 'charlie']

快速建立字典

keys = ["a", "b", "c"]
values = [1, 2, 3]

# 用 zip 和 dict
d = dict(zip(keys, values))

# 用 map 和 lambda
d = dict(map(lambda kv: (kv[0], kv[1] * 2), zip(keys, values)))
print(d)  # {'a': 2, 'b': 4, 'c': 6}

回呼函數

def process_data(data, callback):
    return [callback(item) for item in data]

numbers = [1, 2, 3, 4, 5]

# 使用不同的處理方式
doubled = process_data(numbers, lambda x: x * 2)
squared = process_data(numbers, lambda x: x ** 2)

print(doubled)  # [2, 4, 6, 8, 10]
print(squared)  # [1, 4, 9, 16, 25]