什么是 Lambda 函数?
我们回顾一下 lambda 函数是什么。
lambda 函数是一种匿名函数,意思是它没有函数名,它的语法非常简洁:
lambda arguments: expression
arguments: 参数列表,和普通函数一样。expression: 单个表达式,这个表达式的计算结果就是函数的返回值,注意,lambda只能包含一个表达式,不能有复杂的逻辑(如if-else语句块、for循环等,但三元运算符是允许的)。
示例:
一个普通的 def 函数:
def add(x, y):
return x + y
用 lambda 实现:
add_lambda = lambda x, y: x + y print(add_lambda(3, 5)) # 输出: 8
虽然可以给 lambda 赋值一个变量名,但它通常用完即弃,直接作为参数传递。
为什么要把 Lambda 作为参数传递?
将 lambda 作为参数传递的主要目的是代码简洁性和一次性使用,当你需要传递一个简单的、只有一两行代码的函数时,使用 lambda 可以避免定义一个完整的、有名字的函数,让代码更紧凑、可读性更高。
核心思想: 将“行为”或“操作”作为参数传递给另一个函数。
常见的使用场景
lambda 函数经常和高阶函数(接受函数作为参数的函数)一起使用,最典型的例子就是 Python 的内置函数和一些库(如 pandas)中的函数。
内置函数 sorted()
sorted() 函数可以接受一个 key 参数,key 是一个函数,用于从每个元素中提取一个比较键。
需求: 按照列表中每个字符串的长度进行排序。
words = ["apple", "banana", "cherry", "date", "fig"]
# 方法1:使用 def 定义一个函数
def get_length(s):
return len(s)
sorted_words1 = sorted(words, key=get_length)
print(sorted_words1)
# 输出: ['fig', 'date', 'apple', 'banana', 'cherry']
# 方法2:使用 lambda 函数(更简洁)
sorted_words2 = sorted(words, key=lambda s: len(s))
print(sorted_words2)
# 输出: ['fig', 'date', 'apple', 'banana', 'cherry']
在这个例子中,sorted() 函数会遍历 words 列表中的每一个元素("apple"),然后用 lambda s: len(s) 这个函数来处理它,得到它的长度(5),最后根据这个长度值进行排序。
内置函数 map()
map() 函数会对一个序列中的所有元素应用一个指定的函数,并返回一个迭代器。
需求: 将一个列表中的所有数字都平方。
numbers = [1, 2, 3, 4, 5]
# 方法1:使用 def 定义一个函数
def square(n):
return n * n
squared_numbers1 = list(map(square, numbers))
print(squared_numbers1)
# 输出: [1, 4, 9, 16, 25]
# 方法2:使用 lambda 函数
squared_numbers2 = list(map(lambda n: n * n, numbers))
print(squared_numbers2)
# 输出: [1, 4, 9, 16, 25]
map(lambda n: n * n, numbers) 的意思是:对 numbers 列表中的每一个元素 n,应用 lambda n: n * n 这个函数。
内置函数 filter()
filter() 函数用于过滤序列,过滤掉不符合条件的元素,返回一个迭代器。
需求: 从一个列表中筛选出所有的偶数。
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# 方法1:使用 def 定义一个函数
def is_even(n):
return n % 2 == 0
even_numbers1 = list(filter(is_even, numbers))
print(even_numbers1)
# 输出: [2, 4, 6, 8, 10]
# 方法2:使用 lambda 函数
even_numbers2 = list(filter(lambda n: n % 2 == 0, numbers))
print(even_numbers2)
# 输出: [2, 4, 6, 8, 10]
filter(lambda n: n % 2 == 0, numbers) 的意思是:检查 numbers 列表中的每一个元素 n,lambda n: n % 2 == 0 返回 True,就保留这个元素。
列表的 sort() 方法
列表的 sort() 方法也支持 key 参数,功能和 sorted() 类似,但它是原地排序(修改原列表)。
需求: 对一个元组列表,按照元组的第二个元素进行排序。
students = [('Alice', 85), ('Bob', 92), ('Charlie', 78)]
# 按照分数(元组的第二个元素,索引为1)从高到低排序
students.sort(key=lambda student: student[1], reverse=True)
print(students)
# 输出: [('Bob', 92), ('Alice', 85), ('Charlie', 78)]
Pandas 库(数据分析)
在数据科学领域,lambda 与 apply、map、transform 等方法结合使用极为频繁。
需求: 在 Pandas DataFrame 中,对某一列的数据进行转换。
import pandas as pd
data = {'Name': ['Alice', 'Bob', 'Charlie'], 'Score': [85, 92, 78]}
df = pd.DataFrame(data)
# 创建一个新列 'Grade',根据 Score 来评定等级
df['Grade'] = df['Score'].apply(lambda score: 'A' if score >= 90 else 'B' if score >= 80 else 'C')
print(df)
输出:
Name Score Grade
0 Alice 85 B
1 Bob 92 A
2 Charlie 78 C
这里的 df['Score'].apply(...) 对 Score 列中的每一个 score 值,应用了 lambda score: ... 这个逻辑。
Lambda 的优点与缺点
优点:
- 简洁性:对于简单的函数,
lambda可以用一行代码搞定,避免了def的冗长。 - 即时性:可以在需要的地方直接定义和使用,无需提前声明,代码逻辑更集中。
- 可读性:对于非常简单的操作,
lambda可以让代码意图更清晰,减少了寻找函数定义的麻烦。
缺点:
- 功能受限:
lambda只能包含一个表达式,无法实现复杂的逻辑(如循环、异常处理、多行if-else)。 - 可读性差:
lambda函数变得复杂(比如参数很多或逻辑很绕),它的可读性会急剧下降,反而不如一个命名函数清晰。 - 没有文档字符串:
lambda函数不能有docstring,不方便解释函数的功能。 - 难以调试:由于没有名字,在调试堆栈中追踪
lambda会比较困难。
Lambda 与 functools.partial
lambda 还可以用来创建 functools.partial 对象,这是一种“冻结”函数部分参数的技术。
需求: 创建一个只需要一个参数(基数)的乘法函数。
from functools import partial
# 一个普通的乘法函数
def multiply(x, y):
return x * y
# 使用 lambda 创建一个 "固定" 了第二个参数为 2 的新函数
double = lambda x: multiply(x, 2)
# 使用 functools.partial 实现同样的功能(更符合 Pythonic)
double_partial = partial(multiply, 2)
print(double(5)) # 输出: 10
print(double_partial(5)) # 输出: 10
在这个例子中,lambda x: multiply(x, 2) 和 partial(multiply, 2) 的效果是一样的,都是创建了一个新的函数 double,它只需要一个参数 x,内部会调用 multiply(x, 2)。
| 特性 | def 函数 |
lambda 函数 |
|---|---|---|
| 名称 | 有名称,可重用 | 匿名,通常一次性使用 |
| 语法 | def name(args): ... |
lambda args: expression |
| 复杂性 | 可包含多行代码、逻辑、循环等 | 只能有一个表达式 |
| 文档 | 可添加 docstring |
无法添加 docstring |
| 使用场景 | 复杂逻辑、需要重用、需要文档说明 | 简单操作、作为参数传递、临时使用 |
核心建议:
- 简单逻辑,用
lambda:当函数体只是一个简单的表达式,且只在一处使用时,lambda是绝佳选择。 - 复杂逻辑,用
def:当函数逻辑复杂、需要多行代码、需要被多次调用或需要文档说明时,请使用def定义一个清晰的、有名字的函数。
掌握 lambda 作为参数的用法,是提升 Python 代码简洁性和表达力的重要一步。
