视频加载失败

Python lambda 匿名函数详解

2061 字
10 分钟
Python lambda 匿名函数详解

前言#

在 Python 中,除了用 def 定义有名字的函数,还有一种更简洁的方式来创建一次性使用的小函数——那就是 lambda 匿名函数。

很多初学者觉得 lambda 难以理解,但实际上它只是一个没有名字的、单行表达式函数。一旦掌握,你会发现它在代码中非常实用:

  • 排序时指定自定义规则
  • 配合 map、filter 快速处理数据
  • 作为回调函数传入 GUI 或异步框架
  • 在 pandas 等数据分析库中做列操作

本文将从语法到实战,全面讲解 Python lambda 的用法。


1. lambda 基本语法#

1.1 语法格式#

lambda 参数1, 参数2, ... : 表达式
  • lambda 关键字声明这是一个匿名函数
  • 参数列表可以有多个,用逗号分隔
  • 只能有一个表达式,表达式的结果就是返回值
  • 不能包含语句(如 print、if 语句块、for 循环等)

1.2 最简单的例子#

# def 写法
def add(x, y):
return x + y
# lambda 等价写法
add = lambda x, y: x + y
print(add(3, 5)) # 8
Warning

虽然可以把 lambda 赋值给变量,但 PEP 8 不推荐这样做。如果需要可复用的函数,请直接用 def。lambda 的本意是匿名、一次性使用。

1.3 多参数与无参数#

# 多参数
f = lambda a, b, c: a + b + c
print(f(1, 2, 3)) # 6
# 无参数
import random
get_random = lambda: random.randint(1, 100)
print(get_random()) # 比如 42
# 默认参数
greet = lambda name, greeting="Hello": f"{greeting}, {name}!"
print(greet("World")) # Hello, World!
print(greet("World", "Hi")) # Hi, World!

2. lambda 的常见使用场景#

2.1 配合 sorted() 排序#

这是 lambda 最常见的用法之一。sorted() 的 key 参数接受一个函数,lambda 正好胜任:

students = [
{"name": "Alice", "score": 85},
{"name": "Bob", "score": 92},
{"name": "Charlie", "score": 78},
]
# 按 score 排序
sorted_students = sorted(students, key=lambda s: s["score"])
print(sorted_students)
# [{'name': 'Charlie', 'score': 78}, {'name': 'Alice', 'score': 85}, {'name': 'Bob', 'score': 92}]
# 降序排列
sorted_students_desc = sorted(students, key=lambda s: s["score"], reverse=True)
print(sorted_students_desc)
# [{'name': 'Bob', 'score': 92}, {'name': 'Alice', 'score': 85}, {'name': 'Charlie', 'score': 78}]

更多排序场景:

# 按字符串长度排序
words = ["apple", "banana", "kiwi", "grape"]
sorted_words = sorted(words, key=lambda w: len(w))
print(sorted_words) # ['kiwi', 'grape', 'apple', 'banana']
# 按元组的第二个元素排序
pairs = [(1, 3), (2, 1), (4, 2)]
sorted_pairs = sorted(pairs, key=lambda x: x[1])
print(sorted_pairs) # [(2, 1), (4, 2), (1, 3)]
# 多条件排序(先按 score 降序,再按 name 升序)
students = [
{"name": "Alice", "score": 85},
{"name": "Bob", "score": 85},
{"name": "Charlie", "score": 92},
]
sorted_students = sorted(students, key=lambda s: (-s["score"], s["name"]))
print(sorted_students)
# [{'name': 'Charlie', 'score': 92}, {'name': 'Alice', 'score': 85}, {'name': 'Bob', 'score': 85}]

2.2 配合 map() 批量转换#

map(func, iterable) 对可迭代对象的每个元素应用 func,返回一个迭代器:

numbers = [1, 2, 3, 4, 5]
# 每个数平方
squares = list(map(lambda x: x ** 2, numbers))
print(squares) # [1, 4, 9, 16, 25]
# 摄氏度转华氏度
celsius = [0, 10, 20, 30, 40]
fahrenheit = list(map(lambda c: c * 9/5 + 32, celsius))
print(fahrenheit) # [32.0, 50.0, 68.0, 86.0, 104.0]
# 两个列表对应元素相加
a = [1, 2, 3]
b = [4, 5, 6]
sums = list(map(lambda x, y: x + y, a, b))
print(sums) # [5, 7, 9]
Note

对于简单的转换,列表推导式通常比 map + lambda 更 Pythonic:

squares = [x ** 2 for x in numbers] # 推荐
squares = list(map(lambda x: x ** 2, numbers)) # 可以但不推荐

2.3 配合 filter() 筛选数据#

filter(func, iterable) 保留 func 返回 True 的元素:

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# 筛选偶数
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(evens) # [2, 4, 6, 8, 10]
# 筛选长度大于 3 的字符串
words = ["a", "ab", "abc", "abcd", "abcde"]
long_words = list(filter(lambda w: len(w) > 3, words))
print(long_words) # ['abcd', 'abcde']
# 筛选字典列表
users = [
{"name": "Alice", "age": 25},
{"name": "Bob", "age": 17},
{"name": "Charlie", "age": 30},
]
adults = list(filter(lambda u: u["age"] >= 18, users))
print(adults) # [{'name': 'Alice', 'age': 25}, {'name': 'Charlie', 'age': 30}]
Note

同样,列表推导式通常更清晰:

evens = [x for x in numbers if x % 2 == 0] # 推荐

2.4 配合 reduce() 累积计算#

reduce() 在 Python 3 中被移到了 functools 模块,需要显式导入:

from functools import reduce
# 累加
numbers = [1, 2, 3, 4, 5]
total = reduce(lambda x, y: x + y, numbers)
print(total) # 15
# 阶乘
n = 5
factorial = reduce(lambda x, y: x * y, range(1, n + 1))
print(factorial) # 120
# 找最大值
numbers = [3, 7, 2, 9, 1]
max_val = reduce(lambda x, y: x if x > y else y, numbers)
print(max_val) # 9

2.5 配合 max() / min() 自定义比较#

words = ["apple", "banana", "kiwi", "grape"]
# 找最长的单词
longest = max(words, key=lambda w: len(w))
print(longest) # banana
# 找字典列表中 score 最高的人
students = [
{"name": "Alice", "score": 85},
{"name": "Bob", "score": 92},
{"name": "Charlie", "score": 78},
]
top_student = max(students, key=lambda s: s["score"])
print(top_student) # {'name': 'Bob', 'score': 92}

2.6 在 GUI 和回调中使用#

import tkinter as tk
root = tk.Tk()
# lambda 在 GUI 按钮回调中非常常见
button = tk.Button(
root,
text="Click me",
command=lambda: print("Button clicked!")
)
button.pack()
root.mainloop()

3. lambda 与 if-else 条件表达式#

lambda 不能包含语句块,但可以使用三元条件表达式:

# 判断奇偶
check = lambda x: "偶数" if x % 2 == 0 else "奇数"
print(check(4)) # 偶数
print(check(7)) # 奇数
# 结合 sorted 做复杂排序
data = [5, -3, 2, -8, 1]
# 按绝对值排序
sorted_data = sorted(data, key=lambda x: abs(x))
print(sorted_data) # [1, 2, -3, 5, -8]
# 多条件表达式
grade = lambda score: "A" if score >= 90 else ("B" if score >= 80 else ("C" if score >= 70 else "D"))
print(grade(95)) # A
print(grade(75)) # C
Warning

嵌套的三元表达式会严重降低可读性。如果条件逻辑复杂,请用 def 定义函数。


4. 立即执行 lambda(IIFE)#

lambda 可以定义后立即调用(类似 JavaScript 的 IIFE):

# 定义并立即调用
result = (lambda x, y: x + y)(3, 5)
print(result) # 8
# 在列表推导中使用
results = [(lambda x: x ** 2)(i) for i in range(5)]
print(results) # [0, 1, 4, 9, 16]
Note

这种写法在 Python 中不常见,通常用普通表达式或变量代替即可。了解即可,不必刻意使用。


5. lambda 的局限性与注意事项#

5.1 只能包含单个表达式#

# ❌ 错误:lambda 不能包含语句
# f = lambda x: print(x); return x * 2 # SyntaxError
# ✅ 正确:用 def 代替
def f(x):
print(x)
return x * 2

5.2 闭包与变量捕获(常见陷阱)#

这是 lambda 最经典的坑:

# ❌ 陷阱:所有 lambda 都捕获了同一个变量 i
funcs = []
for i in range(3):
funcs.append(lambda: i)
print([f() for f in funcs]) # [2, 2, 2] 而不是 [0, 1, 2]

原因:lambda 捕获的是变量 i 本身,而不是它的值。循环结束后 i = 2,所有 lambda 引用的都是同一个 i。

解决方案:使用默认参数”冻结”当前值:

# ✅ 正确:用默认参数保存当前值
funcs = []
for i in range(3):
funcs.append(lambda i=i: i) # i=i 创建了默认参数
print([f() for f in funcs]) # [0, 1, 2]

5.3 不要在 lambda 中赋值#

# ❌ 错误:lambda 中不能使用赋值语句
# f = lambda x: y = x + 1 # SyntaxError
# ❌ 错误:海象运算符也不行(Python 3.8+)
# f = lambda x: (y := x + 1) # SyntaxError

5.4 lambda 没有类型注解#

# ❌ lambda 不支持类型注解
# f = lambda x: int, y: int -> int: x + y # 语法错误
# ✅ 如果需要类型注解,请用 def
def add(x: int, y: int) -> int:
return x + y

5.5 可读性优先#

# ❌ 过度使用 lambda,难以阅读
result = list(map(lambda x: x * 2, filter(lambda x: x > 0, [-3, -2, -1, 0, 1, 2, 3])))
# ✅ 用列表推导式,清晰明了
result = [x * 2 for x in [-3, -2, -1, 0, 1, 2, 3] if x > 0]

6. pandas 中的 lambda#

在数据分析中,lambda 经常与 pandas 的 apply()、transform() 搭配:

import pandas as pd
df = pd.DataFrame({
"name": ["Alice", "Bob", "Charlie"],
"score": [85, 92, 78],
})
# 添加一列:评级
df["grade"] = df["score"].apply(lambda x: "优秀" if x >= 90 else ("良好" if x >= 80 else "一般"))
print(df)
# name score grade
# 0 Alice 85 良好
# 1 Bob 92 优秀
# 2 Charlie 78 一般
# 批量处理列名
df.columns = df.columns.map(lambda c: c.upper())
print(df.columns) # Index(['NAME', 'SCORE', 'GRADE'], dtype='object')

7. 总结与最佳实践#

场景推荐做法
sorted() 的 key 参数✅ 用 lambda
max() / min() 的 key 参数✅ 用 lambda
简单的 map() / filter()优先用列表推导式
复杂的转换逻辑用 def 定义函数
需要复用的函数用 def,不要赋给变量
需要类型注解用 def
涉及多行逻辑用 def

核心原则:lambda 适合简单、一次性、作为参数传入的场景。如果函数需要复用、逻辑复杂、或需要文档说明,请用 def。


参考资料#

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

Python lambda 匿名函数详解
https://ksayus.top/posts/python-lambda-guide/
作者
Ksayus
发布于
2026-09-10
许可协议
GPLv3

评论区

Profile Image of the Author
Ksayus
细碎的美好也是生活的意义
Ksayus の 猫窝
This is Ksayus`s blog, is will be write some tech article.
分类
标签
最新动态
站点统计
文章
35
分类
7
标签
111
总字数
58,408
运行时长
0 天
最后活动
0 天前
站点信息
构建平台
GitHub Actions
博客版本
Firefly v6.16.8
文章许可
GPLv3
文章目录