Python lambda 表达式(匿名函数)
摘要
lambda 是 Python 的匿名函数语法,用于创建简单的、一次性使用的函数对象。
基本语法
lambda 参数1, 参数2... : 表达式
对比普通函数
| 普通函数 | lambda 表达式 |
|---|---|
def add(x, y): return x + y | add = lambda x, y: x + y |
限制:lambda 只能包含单个表达式,不能写语句(如赋值、循环、return)。
lambda 的核心价值
lambda 的精髓在于即用即弃,不需要 def 定义,直接作为参数传递给其他函数。
# 场景:对列表排序,按字符串长度而非字母顺序
words = ['apple', 'pie', 'banana']
# 不用 lambda 需要提前定义函数
def by_length(s):
return len(s)
words.sort(key=by_length) # 函数只用一次,却占了命名空间
# 用 lambda 直接内联
words.sort(key=lambda s: len(s))
接受函数作为参数的内置函数
Python 有多个内置高阶函数(Higher-Order Functions),接收函数作为参数。
1. sorted() / list.sort():自定义排序键
students = [('Alice', 85), ('Bob', 92), ('Charlie', 78)]
# 按分数(元组第2个元素)排序
sorted(students, key=lambda x: x[1])
# [('Charlie', 78), ('Alice', 85), ('Bob', 92)]
# 先按分数降序,分数相同按名字升序
sorted(students, key=lambda x: (-x[1], x[0]))
2. map():映射转换
对可迭代对象的每个元素应用函数,返回惰性迭代器。
nums = [1, 2, 3, 4]
# 平方每个数
squares = map(lambda x: x ** 2, nums)
list(squares) # [1, 4, 9, 16]
# 多可迭代对象:两列表对应位置相加
a, b = [1, 2, 3], [10, 20, 30]
sums = map(lambda x, y: x + y, a, b)
list(sums) # [11, 22, 33]
3. filter():条件过滤
保留使函数返回 True 的元素。
nums = [1, 2, 3, 4, 5, 6]
# 保留偶数
evens = filter(lambda x: x % 2 == 0, nums)
list(evens) # [2, 4, 6]
# 保留长度大于3的字符串
words = ['a', 'bb', 'ccc', 'dddd']
long_words = filter(lambda s: len(s) > 3, words)
list(long_words) # ['dddd']
4. reduce():累积归约(需导入 functools)
将序列两两合并,最终得到一个值。
from functools import reduce
nums = [1, 2, 3, 4, 5]
# 累乘:(((1×2)×3)×4)×5 = 120
product = reduce(lambda acc, x: acc * x, nums)
# 找最大值
max_val = reduce(lambda a, b: a if a > b else b, nums)
执行过程可视化:
[1, 2, 3, 4, 5]
↓
1 × 2 = 2
↓
2 × 3 = 6
↓
6 × 4 = 24
↓
24 × 5 = 120
5. max() / min():自定义比较键
words = ['apple', 'pie', 'banana']
# 最长的单词
max(words, key=lambda s: len(s)) # 'banana'
# 数值列表中绝对值最大的(离0最远)
nums = [-5, 3, -10, 2]
max(nums, key=lambda x: abs(x)) # -10
6. 函数汇总表
| 函数 | 作用 | 函数参数意义 | 返回值 |
|---|---|---|---|
sorted(iter, key=func) | 排序 | 提取用于比较的关键字 | 新列表 |
map(func, iter...) | 映射 | 元素转换规则 | 惰性迭代器 |
filter(func, iter) | 过滤 | 保留条件(返回 True 保留) | 惰性迭代器 |
reduce(func, iter) | 归约 | 两两合并规则 | 单个值 |
max/min(iter, key=func) | 最值 | 比较关键字提取 | 单个元素 |
lambda 与这些函数的配合模式
data = [
{'name': 'Alice', 'age': 25, 'score': 85},
{'name': 'Bob', 'age': 30, 'score': 92},
{'name': 'Charlie', 'age': 22, 'score': 78}
]
# 模式1:提取字段排序
by_age = sorted(data, key=lambda d: d['age'])
# 模式2:多字段计算
by_efficiency = sorted(data, key=lambda d: d['score'] / d['age'])
# 模式3:过滤复合条件
adults_high_score = filter(lambda d: d['age'] >= 25 and d['score'] > 80, data)
# 模式4:提取转换
names = map(lambda d: d['name'].upper(), data)
lambda 的局限与替代
| 场景 | lambda 能否处理 | 替代方案 |
|---|---|---|
| 简单表达式(算术、比较、索引) | ✅ 适合 | 直接用 |
| 多语句、赋值、异常处理 | ❌ 不适合 | 用 def 定义普通函数 |
| 逻辑复杂、复用多次 | ❌ 不适合 | 用 def + 有意义的名字 |
# 反例:lambda 强行写复杂逻辑,可读性差
process = lambda x: (y := x.strip().lower(), y.replace('a', '@'))[1] # 别这样
# 正例:复杂逻辑用 def
def process(s):
cleaned = s.strip().lower()
return cleaned.replace('a', '@')
总结
lambda 是胶水:简单逻辑内联传递给高阶函数,避免为小功能污染命名空间。配合 sorted/map/filter/reduce/max/min,可以写出声明式的数据处理代码。