6. lambda 匿名函数

lambda 函数是 Python 中一种特殊的匿名函数,它提供了一种简洁的方式来创建简单的函数。

基本语法

python
# lambda 参数: 表达式
# lambda 是 Python 的关键字,用于定义匿名函数
# 参数可以是零个或多个,多个参数用逗号分隔
# 表达式是函数的返回值,只能有一个表达式

# 对比普通函数与 lambda 函数
add = lambda x, y: x + y
print(add(1, 3))  # 4

def substract(x, y):
    return x - y
print(substract(1, 3))  # -2

▶ 运行结果:

输出
4
-2

lambda 函数的特性

匿名性:lambda 函数没有名称,这也是它被称为匿名函数的原因。通常我们会将它赋值给一个变量,以便重复使用。

python
multiply = lambda a, b: a * b
print(multiply(4, 5))  # 20

print((lambda x, y: x ** y)(5, 2))  # 25

▶ 运行结果:

输出
20
25

lambda 函数的主体只能是一个表达式,不能包含多条语句,也不能使用 return 语句(表达式的结果会自动返回)。

python
# 错误示例(不能写多行语句):
# method = lambda x, y:
#     if x > 0:
#         return x ** y
#     else:
#         return y ** x

# 但可以改成如下形式(使用三元运算符):
method = lambda x, y: x ** y if x > 0 else y ** x

lambda 函数的常见用法

lambda 函数最常见的用途是作为高阶函数(如 map()filter()sorted() 等)的参数。

python
# map():将列表中每个元素平方
arr = [1, 2, 3, 4, 5]
# 等效于 [x ** 2 for x in arr]
print([x ** 2 for x in arr])
arr = list(map(lambda x: x ** 2, arr))
print(arr)  # [1, 4, 9, 16, 25]

# map():处理两个列表
arr1 = [1, 2, 3, 4]
arr2 = [5, 6, 7, 8]
# 等效于 [x * y for x, y in zip(arr1, arr2)]
print([x * y for x, y in zip(arr1, arr2)])
arr3 = list(map(lambda x, y: x * y, arr1, arr2))
print(arr3)  # [5, 12, 21, 32]

▶ 运行结果:

输出
[1, 4, 9, 16, 25]
[1, 4, 9, 16, 25]
[5, 12, 21, 32]
[5, 12, 21, 32]
python
# filter():得到所有的偶数
arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print([x for x in arr if x % 2 == 0])
arr = list(filter(lambda x: x % 2 == 0, arr))
print(arr)  # [2, 4, 6, 8, 10]

# filter():获取所有长度小于等于3的字符串
arr = ['app', 'oppo', 'ab', 'pp', 'abc', 'banana']
print([s for s in arr if len(s) <= 3])
arr = list(filter(lambda s: len(s) <= 3, arr))
print(arr)  # ['app', 'ab', 'pp', 'abc']

▶ 运行结果:

输出
[2, 4, 6, 8, 10]
[2, 4, 6, 8, 10]
['app', 'ab', 'pp', 'abc']
['app', 'ab', 'pp', 'abc']
python
# sorted():按照字符串长度排序
arr = ['apple', 'banan', 'cherry', 'date']
print(sorted(arr))  # 默认按字母顺序
print(sorted(arr, key=lambda s: len(s)))  # 按长度排序

# sorted():按照字典中的值排序
people = [
    {'name': 'alic', 'age': 15},
    {'name': 'charlia', 'age': 30},
    {'name': 'bob', 'age': 25},
]
print(sorted(people, key=lambda x: x['age']))  # 按年龄排序
print(sorted(people, key=lambda x: x['name'][-1]))  # 按姓名最后一个字母排序

words = {"apple": 5, "orange": 6, "banana": 4}
print(sorted(words))  # 传入字典,默认按键排序
print(sorted(words, key=lambda x: words[x], reverse=True))  # 按值降序

▶ 运行结果:

输出
['apple', 'banan', 'cherry', 'date']
['date', 'apple', 'banan', 'cherry']
[{'name': 'alic', 'age': 15}, {'name': 'bob', 'age': 25}, {'name': 'charlia', 'age': 30}]
[{'name': 'charlia', 'age': 30}, {'name': 'bob', 'age': 25}, {'name': 'alic', 'age': 15}]
['apple', 'banana', 'orange']
['orange', 'apple', 'banana']
python
# reduce():累积操作
from functools import reduce

arr = [1, 2, 3, 4, 5]
print(reduce(lambda x, y: x + y, arr))  # 累加:15
print(reduce(lambda x, y: x * y, arr))  # 累乘:120

▶ 运行结果:

输出
15
120

lambda 作为函数的返回值

python
# 传入一个操作符,返回该操作符对应的函数
def make_operation(operator):
    if operator == "+":
        return lambda x, y: x + y
    elif operator == '-':
        return lambda x, y: x - y
    elif operator == '*':
        return lambda x, y: x * y
    elif operator == '/':
        return lambda x, y: x / y
    else:
        return "操作符错误"

add = make_operation("+")
print(add(3, 4))  # 7
multiply = make_operation("*")
print(multiply(3, 4))  # 12

▶ 运行结果:

输出
7
12

lambda 函数的参数形式

python
# 无参数
func = lambda: "Hello World!"
print(func())

# 一个位置参数
func = lambda x: x ** 2
print(func(3))  # 9

# 多个位置参数
func = lambda x, y, z: x * y * z
print(func(1, 2, 3))  # 6

# 默认参数
func = lambda x, y=2: x ** y
print(func(2))       # 4
print(func(2, 3))    # 8
print(func(y=3, x=3))  # 27

# 可变参数
func = lambda *args: [x for x in args if x % 2 == 1]
print(func(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))  # [1, 3, 5, 7, 9]

# 关键字可变参数
func = lambda **kwargs: [f'{key}:{value}' for key, value in kwargs.items() if len(key) == 3]
print(func(name="张三", age=18, height=1.85, sex="男"))  # ['age:18', 'sex:男']

▶ 运行结果:

输出
Hello World!
9
6
4
8
27
[1, 3, 5, 7, 9]
['age:18', 'sex:男']

lambda 与普通函数的选择

适合使用 lambda适合使用 def
函数逻辑简单,只有一行表达式函数逻辑复杂,需要多行代码
作为高阶函数的临时参数(如 sorted、map、filter 等)函数需要被多次复用
需要在短时间内创建简单的函数对象函数需要文档字符串来解释其功能
函数需要处理异常