Python lambda 用来写只含一个表达式的匿名函数。它不会替代 def,而是适合塞进 sortedfiltermap 这类需要临时传入一小段规则的参数位。逻辑一旦变长、要多语句,就改回 def

和 def 对比

下面两个 double 对同一个输入给出相同结果。差别在于:lambda 没有独立的函数体块,返回值就是冒号右边那个表达式:

def double(x):
    return x * 2

double2 = lambda x: x * 2

print(double(5))     # 10
print(double2(5))    # 10

语法

形式是 lambda 参数列表: 表达式。可以有多个参数,也可以在表达式里写三元判断,但不能写赋值语句或多条语句:

Python lambda 匿名函数示例运行
add = lambda a, b: a + b
print(add(3, 4))            # 7

max2 = lambda a, b: a if a > b else b
print(max2(3, 7))           # 7

给 sorted 当 key

sortedkey 需要一个可调用对象:接收元素,返回排序依据。元组列表按成绩排、按名字长度排,都可以用一行 lambda 描述依据:

students = [("Tom", 88), ("Ann", 95), ("Bob", 72)]

top = sorted(students, key=lambda s: s[1], reverse=True)
print(top)   # [('Ann', 95), ('Tom', 88), ('Bob', 72)]

by_len = sorted(students, key=lambda s: len(s[0]))
print(by_len)

配合 filter

filter 保留让谓词为真的元素。谓词同样可以是 lambda。结果是迭代器,需要列表时再包 list

nums = [1, 2, 3, 4, 5, 6]
evens = list(filter(lambda x: x % 2 == 0, nums))
print(evens)   # [2, 4, 6]

配合 map

map 对每个元素做同一变换。列表推导往往更直观,但读旧代码时仍常见 map + lambda:

nums = [1, 2, 3]
squares = list(map(lambda x: x * x, nums))
print(squares)   # [1, 4, 9]

names = ["tom", "ann"]
cap = list(map(lambda n: n.title(), names))
print(cap)   # ['Tom', 'Ann']

和 def 怎么选

特点deflambda
用途具名函数,可能多处复用一次性小规则,常作参数
可读性逻辑长时更清楚超过一个表达式就难读
函数体可多行、可语句只能一个表达式
文档字符串可以写不能写

规则很短、只在调用处出现一次,用 lambda 更省事。要起名字、写说明、或包含多步逻辑,用 def

常见误区

  • lambda 里不能写多条语句,也不要依赖分号硬拼。
  • 表达式一旦绕到要瞪着看半天才懂,就换成 def
  • 在循环里创建 lambda 时,若表达式引用了循环变量,捕获的是变量本身而不是当时的值,事后调用可能全变成最后一轮的结果。需要绑定当前值时,用默认参数把值冻住,例如 lambda n=i: n