Skip to content

Python lambda(匿名函数)

lambda 函数是 Python 中的一种匿名函数,它可以在一行代码中定义简单的函数。本章节将详细介绍 Python 中的 lambda 函数及其用法。

基本概念

lambda 函数是一种小型、匿名的函数,它使用 lambda 关键字定义,而不是 def 关键字。lambda 函数通常用于需要一个简单函数作为参数的场合,比如在 map()filter()sorted() 等函数中。

基本语法

python
lambda parameters: expression
  • lambda:定义 lambda 函数的关键字。
  • parameters:函数的参数列表,可选,可以有多个参数,用逗号分隔。
  • expression:函数的返回值表达式,必须是单个表达式,不能包含多条语句。

示例

基本用法

python
# lambda 函数的基本用法

# 定义一个简单的 lambda 函数
add = lambda x, y: x + y

# 调用 lambda 函数
result = add(3, 5)
print(f"3 + 5 = {result}")  # 输出:3 + 5 = 8

# 定义一个计算平方的 lambda 函数
square = lambda x: x ** 2

# 调用 lambda 函数
result = square(4)
print(f"4 的平方 = {result}")  # 输出:4 的平方 = 16

# 定义一个无参数的 lambda 函数
greet = lambda: "Hello, World!"

# 调用 lambda 函数
result = greet()
print(result)  # 输出:Hello, World!

# 定义一个带默认参数的 lambda 函数
power = lambda x, n=2: x ** n

# 调用 lambda 函数
result = power(3)
print(f"3 的 2 次方 = {result}")  # 输出:3 的 2 次方 = 9

result = power(3, 3)
print(f"3 的 3 次方 = {result}")  # 输出:3 的 3 次方 = 27

与 map() 函数一起使用

map() 函数用于将一个函数应用于可迭代对象的每个元素,返回一个迭代器。

示例:

python
# lambda 函数与 map() 函数一起使用

# 计算列表中每个元素的平方
numbers = [1, 2, 3, 4, 5]
squared_numbers = list(map(lambda x: x ** 2, numbers))
print(f"原列表:{numbers}")
print(f"平方后的列表:{squared_numbers}")  # 输出:[1, 4, 9, 16, 25]

# 将列表中的字符串转换为大写
names = ["alice", "bob", "charlie"]
uppercase_names = list(map(lambda x: x.upper(), names))
print(f"原列表:{names}")
print(f"大写后的列表:{uppercase_names}")  # 输出:['ALICE', 'BOB', 'CHARLIE']

# 计算两个列表对应元素的和
list1 = [1, 2, 3, 4, 5]
list2 = [6, 7, 8, 9, 10]
sum_list = list(map(lambda x, y: x + y, list1, list2))
print(f"列表 1:{list1}")
print(f"列表 2:{list2}")
print(f"对应元素的和:{sum_list}")  # 输出:[7, 9, 11, 13, 15]

与 filter() 函数一起使用

filter() 函数用于过滤可迭代对象中的元素,返回一个迭代器,只包含满足条件的元素。

示例:

python
# lambda 函数与 filter() 函数一起使用

# 过滤出列表中的偶数
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
print(f"原列表:{numbers}")
print(f"偶数列表:{even_numbers}")  # 输出:[2, 4, 6, 8, 10]

# 过滤出列表中的正数
numbers = [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]
positive_numbers = list(filter(lambda x: x > 0, numbers))
print(f"原列表:{numbers}")
print(f"正数列表:{positive_numbers}")  # 输出:[1, 2, 3, 4, 5]

# 过滤出列表中长度大于 3 的字符串
names = ["alice", "bob", "charlie", "david", "eve"]
long_names = list(filter(lambda x: len(x) > 3, names))
print(f"原列表:{names}")
print(f"长度大于 3 的字符串:{long_names}")  # 输出:['alice', 'charlie', 'david']

与 sorted() 函数一起使用

sorted() 函数用于对可迭代对象进行排序,返回一个新的排序后的列表。

示例:

python
# lambda 函数与 sorted() 函数一起使用

# 按默认顺序排序
numbers = [5, 2, 9, 1, 5, 6]
sorted_numbers = sorted(numbers)
print(f"原列表:{numbers}")
print(f"排序后的列表:{sorted_numbers}")  # 输出:[1, 2, 5, 5, 6, 9]

# 按降序排序
sorted_numbers_desc = sorted(numbers, reverse=True)
print(f"降序排序后的列表:{sorted_numbers_desc}")  # 输出:[9, 6, 5, 5, 2, 1]

# 按字符串长度排序
names = ["alice", "bob", "charlie", "david", "eve"]
sorted_names_by_length = sorted(names, key=lambda x: len(x))
print(f"原列表:{names}")
print(f"按长度排序后的列表:{sorted_names_by_length}")  # 输出:['bob', 'eve', 'alice', 'david', 'charlie']

# 按元组的第二个元素排序
tuples = [(1, 5), (2, 3), (3, 1), (4, 4), (5, 2)]
sorted_tuples_by_second = sorted(tuples, key=lambda x: x[1])
print(f"原列表:{tuples}")
print(f"按第二个元素排序后的列表:{sorted_tuples_by_second}")  # 输出:[(3, 1), (5, 2), (2, 3), (4, 4), (1, 5)]

# 按字典的某个键排序
dicts = [
    {"name": "alice", "age": 30},
    {"name": "bob", "age": 25},
    {"name": "charlie", "age": 35},
    {"name": "david", "age": 28}
]
sorted_dicts_by_age = sorted(dicts, key=lambda x: x["age"])
print(f"原列表:{dicts}")
print(f"按年龄排序后的列表:{sorted_dicts_by_age}")  # 输出:[{'name': 'bob', 'age': 25}, {'name': 'david', 'age': 28}, {'name': 'alice', 'age': 30}, {'name': 'charlie', 'age': 35}]

与 reduce() 函数一起使用

reduce() 函数用于对可迭代对象中的元素进行累积操作,返回一个单一的值。在 Python 3 中,reduce() 函数被移到了 functools 模块中。

示例:

python
# lambda 函数与 reduce() 函数一起使用

from functools import reduce

# 计算列表中元素的和
numbers = [1, 2, 3, 4, 5]
sum_numbers = reduce(lambda x, y: x + y, numbers)
print(f"列表:{numbers}")
print(f"元素的和:{sum_numbers}")  # 输出:15

# 计算列表中元素的乘积
product_numbers = reduce(lambda x, y: x * y, numbers)
print(f"元素的乘积:{product_numbers}")  # 输出:120

# 找出列表中的最大值
max_number = reduce(lambda x, y: x if x > y else y, numbers)
print(f"最大值:{max_number}")  # 输出:5

# 找出列表中的最小值
min_number = reduce(lambda x, y: x if x < y else y, numbers)
print(f"最小值:{min_number}")  # 输出:1

# 连接列表中的字符串
strings = ["Hello", " ", "World", "!"]
connected_string = reduce(lambda x, y: x + y, strings)
print(f"字符串列表:{strings}")
print(f"连接后的字符串:{connected_string}")  # 输出:Hello World!

lambda 函数的特点

  1. 匿名性:lambda 函数没有名称,是一种匿名函数。
  2. 简洁性:lambda 函数通常只包含一行代码,非常简洁。
  3. 局限性:lambda 函数只能包含一个表达式,不能包含多条语句。
  4. 返回值:lambda 函数会自动返回表达式的结果,不需要使用 return 语句。
  5. 闭包:lambda 函数可以访问外部作用域的变量。

闭包示例

python
# lambda 函数作为闭包

def make_multiplier(n):
    """返回一个乘以 n 的函数"""
    return lambda x: x * n

# 创建一个乘以 2 的函数
double = make_multiplier(2)
print(double(5))  # 输出:10
print(double(10))  # 输出:20

# 创建一个乘以 3 的函数
triple = make_multiplier(3)
print(triple(5))  # 输出:15
print(triple(10))  # 输出:30

# 另一个闭包示例
def make_greeter(greeting):
    """返回一个带有特定问候语的函数"""
    return lambda name: f"{greeting}, {name}!"

# 创建一个使用 "Hello" 的问候函数
hello_greeter = make_greeter("Hello")
print(hello_greeter("Alice"))  # 输出:Hello, Alice!

# 创建一个使用 "Hi" 的问候函数
hi_greeter = make_greeter("Hi")
print(hi_greeter("Bob"))  # 输出:Hi, Bob!

lambda 函数 vs 普通函数

相同点

  1. 都可以接受参数。
  2. 都可以返回值。
  3. 都可以被调用。

不同点

特性lambda 函数普通函数
定义方式使用 lambda 关键字使用 def 关键字
名称匿名,没有名称有名称
代码长度通常只有一行可以有多行
复杂度适合简单的操作适合复杂的操作
文档字符串不支持支持
语句数量只能包含一个表达式可以包含多个语句
适用场景作为参数传递给其他函数作为独立的代码块

示例对比

python
# lambda 函数 vs 普通函数

# 普通函数
def add(x, y):
    return x + y

# lambda 函数
add_lambda = lambda x, y: x + y

# 调用
print(add(3, 5))  # 输出:8
print(add_lambda(3, 5))  # 输出:8

# 普通函数
def is_even(x):
    return x % 2 == 0

# lambda 函数
is_even_lambda = lambda x: x % 2 == 0

# 调用
print(is_even(4))  # 输出:True
print(is_even_lambda(4))  # 输出:True

应用场景

lambda 函数在以下场景中特别有用:

  1. 作为参数传递:当需要一个简单的函数作为参数传递给其他函数时,如 map()filter()sorted() 等。
  2. 闭包:当需要创建一个闭包时,lambda 函数可以简洁地实现。
  3. 临时函数:当需要一个临时的、一次性使用的函数时,lambda 函数是一个好选择。
  4. 简单的数学运算:当需要进行简单的数学运算时,lambda 函数可以一行搞定。
  5. 排序和比较:当需要自定义排序规则时,lambda 函数可以作为 key 参数传递给 sorted() 函数。

实际应用示例

python
# lambda 函数的实际应用示例

# 1. 作为参数传递
print("1. 作为参数传递")
numbers = [1, 2, 3, 4, 5]

# 使用 map() 函数
print("使用 map() 函数:")
squared = list(map(lambda x: x ** 2, numbers))
print(squared)  # 输出:[1, 4, 9, 16, 25]

# 使用 filter() 函数
print("\n使用 filter() 函数:")
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(evens)  # 输出:[2, 4]

# 使用 sorted() 函数
print("\n使用 sorted() 函数:")
tuples = [(1, 5), (2, 3), (3, 1), (4, 4)]
sorted_by_second = sorted(tuples, key=lambda x: x[1])
print(sorted_by_second)  # 输出:[(3, 1), (2, 3), (4, 4), (1, 5)]

# 2. 闭包
print("\n2. 闭包")
def power_of(n):
    return lambda x: x ** n

cube = power_of(3)
print(cube(2))  # 输出:8
print(cube(3))  # 输出:27

# 3. 临时函数
print("\n3. 临时函数")
# 计算两个数的和,只使用一次
result = (lambda x, y: x + y)(10, 20)
print(result)  # 输出:30

# 4. 简单的数学运算
print("\n4. 简单的数学运算")
# 计算圆的面积
area = lambda r: 3.14159 * r ** 2
print(area(5))  # 输出:78.53975

# 5. 排序和比较
print("\n5. 排序和比较")
# 按字符串长度排序
words = ["apple", "banana", "cherry", "date"]
sorted_by_length = sorted(words, key=lambda x: len(x))
print(sorted_by_length)  # 输出:['date', 'apple', 'cherry', 'banana']

# 按字典值排序
dict_items = {"a": 3, "b": 1, "c": 2}
sorted_items = sorted(dict_items.items(), key=lambda x: x[1])
print(sorted_items)  # 输出:[('b', 1), ('c', 2), ('a', 3)]

注意事项

  1. 可读性:虽然 lambda 函数简洁,但过度使用会降低代码的可读性,特别是对于复杂的逻辑。
  2. 复杂度:lambda 函数只适合简单的操作,对于复杂的逻辑,应该使用普通函数。
  3. 调试:lambda 函数没有名称,调试时可能会比较困难。
  4. 作用域:lambda 函数可以访问外部作用域的变量,但这些变量是按引用传递的,不是按值传递的。

作用域示例

python
# lambda 函数的作用域

# 外部变量
x = 10

# lambda 函数访问外部变量
f = lambda y: x + y
print(f(5))  # 输出:15

# 修改外部变量
x = 20
print(f(5))  # 输出:25(lambda 函数访问的是最新的 x 值)

# 另一个示例
def create_funcs():
    funcs = []
    for i in range(5):
        # 注意:这里的 i 是按引用传递的
        funcs.append(lambda: i)
    return funcs

funcs = create_funcs()
for f in funcs:
    print(f(), end=" ")  # 输出:4 4 4 4 4(所有函数都引用了同一个 i,最后 i 的值是 4)
print()

# 解决方法:使用默认参数

def create_funcs_fixed():
    funcs = []
    for i in range(5):
        # 使用默认参数,将当前的 i 值绑定到函数
        funcs.append(lambda i=i: i)
    return funcs

funcs_fixed = create_funcs_fixed()
for f in funcs_fixed:
    print(f(), end=" ")  # 输出:0 1 2 3 4
print()

总结

lambda 函数是 Python 中的一种匿名函数,它使用 lambda 关键字定义,通常用于需要一个简单函数作为参数的场合。lambda 函数的特点是简洁、匿名,但只能包含一个表达式,适合处理简单的逻辑。

lambda 函数在以下场景中特别有用:

  1. 作为参数传递给其他函数,如 map()filter()sorted() 等。
  2. 创建闭包,封装一些简单的逻辑。
  3. 定义临时的、一次性使用的函数。
  4. 进行简单的数学运算。
  5. 自定义排序规则。

虽然 lambda 函数简洁,但过度使用会降低代码的可读性,对于复杂的逻辑,应该使用普通函数。