讲解
lambda 是创建小型匿名函数的语法:lambda 参数: 表达式。它只能写一个表达式,表达式的结果就是返回值——没有函数体、没有语句、没有 return。lambda 存在的意义是「就地定义一次性小函数」,最典型的用途是作为 key 参数传给 sorted、min、max:sorted(students, key=lambda s: s['score']) 按分数排序,一行搞定,不必专门 def 一个只用一次的函数。
除了排序 key,lambda 还常见于 map、filter、sorted 的直接配合(虽然列表推导式往往更清晰),以及 GUI 编程里的回调。要克制使用:逻辑超过一行表达式就该老老实实 def。判断标准很简单——如果这个函数值得有个名字,就给它名字;lambda 只适合「看一眼就懂」的转换和提取。
sorted 的 key 用法再展开一点:key 函数对每个元素算出排序依据,原元素本身不变。min/max 也接受 key:max(students, key=lambda s: s['score']) 返回分数最高的整个学生字典。operator 模块的 itemgetter、attrgetter 是 lambda 的高效替代:key=itemgetter('score') 等价于 lambda s: s['score'],稍快且更可读,值得认识。
示例
# lambda 基本形态
square = lambda x: x * x
print('lambda 赋值给变量:', square(5))
# 排序 key:lambda 的主场
students = [
{'name': '小明', 'score': 88},
{'name': '小红', 'score': 95},
{'name': '小刚', 'score': 72},
]
by_score = sorted(students, key=lambda s: s['score'], reverse=True)
print('按分数:', [s['name'] for s in by_score])
words = ['banana', 'fig', 'apple']
print('按长度:', sorted(words, key=lambda w: len(w)))
print('按最后一个字母:', sorted(words, key=lambda w: w[-1]))
# min/max 也用 key
best = max(students, key=lambda s: s['score'])
print('最高分同学:', best['name'], best['score'])
# 多关键字:key 返回元组
pairs = [(1, 'b'), (2, 'a'), (1, 'a')]
print('双关键字:', sorted(pairs, key=lambda p: (p[0], p[1])))
# itemgetter:lambda 的干练替代
from operator import itemgetter
print('itemgetter 等价写法:', sorted(students, key=itemgetter('score'))[0]['name'])
# map/filter 配合 lambda(推导式往往更直观,见后面章节)
nums = [1, 2, 3, 4, 5]
print('map:', list(map(lambda n: n * n, nums)))
print('filter:', list(filter(lambda n: n % 2 == 0, nums)))
常见坑
- 在 lambda 里写语句:lambda 只接受一个表达式,lambda x: print(x) if x else None 这类塞语句的写法是语法错误。复杂逻辑用 def。
- 循环里闭包捕获同一变量:funcs = [lambda: i for i in range(3)] 三个函数都返回 2——lambda 捕获的是变量不是值。要固定值用 lambda i=i: i。
- 给 lambda 起名字当常规函数用:PEP 8 明确不推荐 f = lambda x: ...,需要名字就用 def,调试时栈信息才有可读的名字。
- 为了用 lambda 而用 lambda:[xx for x in nums] 比 list(map(lambda x: xx, nums)) 更 Pythonic,推导式一章会细讲。
小结
lambda 写一次性表达式小函数,主场是 sorted/min/max 的 key;复杂逻辑回 def;itemgetter 是干练替代。下一节讲变量在哪儿可见:作用域。