人人都会AI编程

9.5 匿名函数 lambda、高阶函数 map/filter/reduce

更新时间:2026-07-12

在 Python 函数体系中,除了用 def 定义的具名函数,还提供了匿名函数 lambda 以及配合使用的高阶函数mapfilterreduce),让某些轻量级逻辑可以更简洁地表达。

匿名函数 lambda

lambda 关键字用来创建一个小型匿名函数,语法是 lambda 参数: 表达式,只有一行,表达式的结果会被自动返回。

典型场景:临时需要一个简单函数,单独用 def 定义显得啰嗦,比如作为 sorted 的排序键或 map 的处理函数。

# 用 lambda 作为排序键:按字符串长度排序
words = ['apple', 'banana', 'cherry', 'date']
sorted(words, key=lambda word: len(word))  # ['date', 'apple', 'banana', 'cherry']

需要注意的限制

  • lambda 内部只能写一个表达式,不能包含赋值、循环、return 等语句。
  • 可读性优先:如果逻辑稍微复杂(比如多条件判断、多步骤处理),还是用 def 定义具名函数更清晰,强行塞进 lambda 会降低代码的可维护性。
  • lambda 也可以像普通函数一样使用默认参数:lambda x, y=10: x + y

高阶函数 map/filter/reduce

高阶函数指接收函数作为参数返回函数作为结果的函数。mapfilterreduce 是 Python 内置的典型代表,很多开发者早期会使用它们,但现在有了列表推导式和生成器表达式,部分场景已有了更 Pythonic 的替代写法。

map(func, iterable)
对可迭代对象中的每个元素调用 func,返回一个迭代器,包含每次调用的结果。

# 将列表中的每个数字平方
numbers = [1, 2, 3, 4]
squares = map(lambda x: x**2, numbers)
list(squares)  # [1, 4, 9, 16]

更 Pythonic 的写法:直接使用列表推导式,可读性更好。

[x**2 for x in numbers]

filter(func, iterable)
对可迭代对象中的每个元素调用 func保留返回值为 True 的元素,返回迭代器。

# 过滤出偶数
even = filter(lambda x: x % 2 == 0, numbers)
list(even)  # [2, 4]

同样,列表推导式更直观:

[x for x in numbers if x % 2 == 0]

reduce(func, iterable [, initial])
这个函数在 functools 模块中(Python 3 移到了这里)。它累积地func 应用到序列上,把前一次调用的结果和下一个元素作为参数,最终缩减为单个值。

from functools import reduce

# 累加求和
total = reduce(lambda acc, x: acc + x, numbers)
total  # 10

对于求和、求积这类操作,Python 提供了更直接的内置函数 summath.prod,多数情况下直接用内置函数更好。

选择建议

  • 如果你的逻辑很简单(如 x**2),用列表推导式比 map + lambda 更清晰,也更符合 Python 社区惯例。
  • filter 可以用带 if 的列表推导式替代。
  • reduce 使用频率较低,当需要复杂的累积逻辑(比如串联多个操作)时才会考虑,但要确保代码依然易于理解。
  • lambda 本身作为“一次性小函数”依然有用,尤其适合 sortedmaxkey 参数,或 GUI 回调等场景,但不要为了让代码“看起来高级”而滥用。

总之,把这些工具理解为函数式编程风格的一个体现,根据实际场景选用,目的是让代码简洁且可读,而非刻意炫技。