在 Python 函数体系中,除了用 def 定义的具名函数,还提供了匿名函数 lambda 以及配合使用的高阶函数(map、filter、reduce),让某些轻量级逻辑可以更简洁地表达。
匿名函数 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
高阶函数指接收函数作为参数或返回函数作为结果的函数。map、filter、reduce 是 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 提供了更直接的内置函数 sum、math.prod,多数情况下直接用内置函数更好。
选择建议
- 如果你的逻辑很简单(如
x**2),用列表推导式比map+lambda更清晰,也更符合 Python 社区惯例。 filter可以用带if的列表推导式替代。reduce使用频率较低,当需要复杂的累积逻辑(比如串联多个操作)时才会考虑,但要确保代码依然易于理解。lambda本身作为“一次性小函数”依然有用,尤其适合sorted、max的key参数,或 GUI 回调等场景,但不要为了让代码“看起来高级”而滥用。
总之,把这些工具理解为函数式编程风格的一个体现,根据实际场景选用,目的是让代码简洁且可读,而非刻意炫技。