在 Python 中,lambda 用于定义仅含单个表达式的匿名函数,不能替代完整的 def,但适合作为 sorted、filter、map 等函数的短回调。若逻辑需多行语句或需文档说明,应改用 def。本节说明 lambda 语法及其与内置高阶函数的配合。

与 def 的对比

下列两种写法对同一输入产生相同结果;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

sorted 的 key 须为可调用对象:接收元素并返回排序依据。按元组中某一字段或字符串长度排序时,常用一行 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 与 lambda 的选择

特点deflambda
用途具名函数,可多处复用一次性短规则,常作实参
可读性逻辑较长时更清晰超过单表达式时难读
函数体可多行、可含语句仅允许一个表达式
文档字符串可写不可写

规则简短且仅于调用处使用一次时,lambda 较紧凑;需命名、文档或多步逻辑时,应使用 def。

常见错误

  • lambda 内不能写多条语句,不宜用分号强行拼接。
  • 表达式过于复杂、可读性下降时,应改为 def。
  • 在循环中创建 lambda 且引用循环变量时,捕获的是变量本身而非当时的值,事后调用可能均得到最后一轮的值;须绑定当前值时,可用默认参数冻结,例如 lambda n=i: n。

本节说明了 Python 中 lambda 的语法及与内置高阶函数的配合。下一节介绍作用域:LEGB 规则、global 与 nonlocal。