文章
合集Python 语言基础第 13 / 21 篇

Python lambda 表达式(匿名函数)

摘要

lambda 是 Python 的匿名函数语法,用于创建简单的、一次性使用的函数对象。

基本语法

lambda 参数1, 参数2... : 表达式

对比普通函数

普通函数lambda 表达式
def add(x, y): return x + yadd = 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,可以写出声明式的数据处理代码。