Lambda 表达式
Lambda 表达式是创建小型匿名函数的快捷方式。它适合只需要一行代码的简单函数,常用于排序、过滤、映射等场景。
基本语法
# 普通函数
def square(x):
return x ** 2
# 等价 lambda
square = lambda x: x ** 2
print square(5) # 25
语法:lambda 参数: 表达式。Lambda 只能包含一个表达式,不能包含语句(如 if、for、while、return)。
多参数 Lambda
add = lambda x, y: x + y
print add(3, 5) # 8
# 无参数
get_one = lambda: 1
print get_one() # 1
# 默认参数
multiply = lambda x, y=2: x * y
print multiply(5) # 10
print multiply(5, 3) # 15
实际应用场景
排序 key:
students = [
{"name": "Alice", "score": 85},
{"name": "Bob", "score": 92},
{"name": "Charlie", "score": 78},
]
# 按分数排序
students.sort(key=lambda s: s["score"])
for s in students:
print s["name"], s["score"]
# 按名字长度排序
students.sort(key=lambda s: len(s["name"]))
过滤:
nums = [1, 2, 3, 4, 5, 6]
evens = filter(lambda x: x % 2 == 0, nums)
print list(evens) # [2, 4, 6]
映射:
nums = [1, 2, 3, 4]
squares = map(lambda x: x ** 2, nums)
print list(squares) # [1, 4, 9, 16]
闭包:
def make_multiplier(n):
return lambda x: x * n
double = make_multiplier(2)
triple = make_multiplier(3)
print double(5) # 10
print triple(5) # 15
Lambda 的限制
Lambda 只能包含表达式,不能包含语句:
# 错误:lambda 中不能赋值
# lambda x: y = x + 1
# 错误:lambda 中不能用 print 语句(Python 2)
# lambda x: print x
# 正确:用条件表达式
is_even = lambda x: "even" if x % 2 == 0 else "odd"
print is_even(4) # even
print is_even(3) # odd
如果需要多条语句,必须用普通 def 函数。
Lambda vs 普通函数
| 特性 | Lambda | def |
|---|---|---|
| 名字 | 匿名(可赋值给变量) | 有名字 |
| 语句数 | 只能一个表达式 | 任意数量 |
| 可读性 | 简单场景好 | 复杂逻辑好 |
| 调试 | 堆栈跟踪显示 <lambda> | 显示函数名 |
何时用 Lambda,何时用 def
用 Lambda:
- 简单的一次性函数
- 作为参数传递(排序 key、过滤条件)
- 闭包场景
用 def:
- 函数逻辑超过一行
- 需要文档字符串
- 需要递归
- 需要被多次复用
# 推荐:简单排序 key
items.sort(key=lambda x: x["price"])
# 不推荐:复杂的 lambda
items.sort(key=lambda x: (x["price"] * (1 - x["discount"])) / x["quantity"])
# 推荐:复杂的逻辑用命名函数
def effective_price(item):
return (item["price"] * (1 - item["discount"])) / item["quantity"]
items.sort(key=effective_price)
列表推导式替代 Lambda
很多 map/filter + lambda 的场景可以用列表推导式替代,更 Pythonic:
nums = [1, 2, 3, 4, 5, 6]
# map + lambda
evens = map(lambda x: x ** 2, filter(lambda x: x % 2 == 0, nums))
# 列表推导式(推荐)
evens = [x ** 2 for x in nums if x % 2 == 0]