第13课 - Lambda 表达式与高阶函数
课程路径:Python 编程:从零基础到精通 -> 模块三:函数
难度:Intermediate
标签:lambda, higher-order-functions, map, filter
上一课:返回值与作用域(LEGB)
下一课:模块、包与导入机制
1. 学习目标
完成本课学习后,你将能够:
- 理解并正确使用
lambda表达式来创建匿名函数。 - 掌握高阶函数的概念,并能将函数作为参数传递给其他函数。
- 熟练使用 Python 内置的高阶函数
map、filter和sorted。 - 能够结合使用
lambda与高阶函数来处理常见的数据序列操作。
2. 核心概念
什么是 Lambda 表达式?
Lambda 表达式是一种用来创建匿名(即没有名字)的、简单的、一次性使用的小函数的方法。你可以把它看作是一个"即用即扔"的函数定义。
想象一下,你需要一个函数来快速计算一个数的平方,但这个函数只会在一个地方用一次。你还会用 def 去定义一个正式的函数吗?Lambda 就是为这种场景设计的。
语法:lambda 参数1, 参数2, ... : 表达式
lambda是关键字。- 冒号(
:)前面是函数的参数。 - 冒号后面是函数的返回值,必须是一个单一的表达式,不能是复杂的代码块(如
if-else语句,但三元表达式除外)。
# 传统函数定义
def square(x):
return x ** 2
# 等价的 Lambda 表达式
square_lambda = lambda x: x ** 2
print(square(5)) # 输出: 25
print(square_lambda(5)) # 输出: 25
什么是高阶函数?
高阶函数(Higher-Order Function)是指满足以下任一条件的函数:
- 接受一个或多个函数作为输入参数。
- 返回一个函数作为输出结果。
简单说,函数可以像数字、字符串一样被传递和操作。这是 Python 函数式编程特性的重要体现。
# 这是一个高阶函数:它接受一个函数 `operation` 作为参数。
def calculate(func, a, b):
return func(a, b)
# 定义两个简单的函数
def add(x, y):
return x + y
def multiply(x, y):
return x * y
# 将函数作为参数传递
result_add = calculate(add, 3, 4)
result_multiply = calculate(multiply, 3, 4)
print(result_add) # 输出: 7
print(result_multiply) # 输出: 12
map、filter、sorted 等都是 Python 中著名的内置高阶函数。
3. 代码示例
# 示例 1:Lambda 表达式基础
# 定义一个接受两个参数并返回它们之和的 lambda
add = lambda x, y: x + y
print(add(10, 20)) # 输出: 30
# Lambda 非常适合作为函数的参数
print((lambda a, b: a * b)(5, 6)) # 输出: 30
# 示例 2:与 map 结合使用
# map(函数, 可迭代对象): 将函数依次作用于可迭代对象的每个元素
numbers = [1, 2, 3, 4, 5]
# 传统写法
squares = []
for n in numbers:
squares.append(n ** 2)
# 使用 map 和 lambda 的简洁写法
squares_map = list(map(lambda x: x ** 2, numbers))
print(squares) # 输出: [1, 4, 9, 16, 25]
print(squares_map) # 输出: [1, 4, 9, 16, 25]
# 示例 3:与 filter 结合使用
# filter(函数, 可迭代对象): 根据函数返回的布尔值来过滤元素(保留函数返回 True 的元素)
ages = [15, 22, 10, 18, 30, 5, 25]
adults = list(filter(lambda age: age >= 18, ages))
print(adults) # 输出: [22, 18, 30, 25]
# 示例 4:与 sorted 结合使用
# sorted(可迭代对象, key=函数): key 参数接受一个函数,用于指定排序的依据
students = [("Alice", 88), ("Bob", 95), ("Charlie", 70)]
# 按成绩从高到低排序
sorted_by_score = sorted(students, key=lambda student: student[1], reverse=True)
print(sorted_by_score)
# 输出: [('Bob', 95), ('Alice', 88), ('Charlie', 70)]
4. 实践练习
练习题 1(基础):
给定一个单词列表 words = ["apple", "banana", "cherry", "date"],使用 map 和 lambda 将每个单词转换为大写(.upper()),并打印结果列表。
预期输出:['APPLE', 'BANANA', 'CHERRY', 'DATE']
练习题 2(进阶):
请自己实现一个类似于 map 的高阶函数,命名为 my_map。它接受两个参数:一个函数 func 和一个列表 lst。函数应该返回一个新列表,其中包含将 func 应用到 lst 中每个元素的结果。
预期输出:
result = my_map(lambda x: x * 2, [1, 2, 3])
print(result) # 输出: [2, 4, 6]
练习题 3(综合应用):
处理一个学生成绩的字典列表:
student_scores = [
{"name": "Tom", "score": 85},
{"name": "Jerry", "score": 92},
{"name": "Mickey", "score": 78}
]
请使用 sorted 和 lambda 完成以下任务:
a) 按照学生姓名(name)的字母顺序排序。
b) 按照成绩(score)从低到高排序。
预期输出:
[{'name': 'Jerry', 'score': 92}, {'name': 'Mickey', 'score': 78}, {'name': 'Tom', 'score': 85}]
[{'name': 'Mickey', 'score': 78}, {'name': 'Tom', 'score': 85}, {'name': 'Jerry', 'score': 92}]
5. 常见错误
-
试图在 Lambda 中写复杂逻辑:
# 错误:Lambda 中不能包含语句(如 print、if...else... 作为语句块) # bad_lambda = lambda x: if x > 0: print("positive") else: print("non-positive") # 修正:可以使用三元表达式,但打印操作仍需包装 action = lambda x: print("positive") if x > 0 else print("non-positive")建议:Lambda 适合单一表达式。如果逻辑复杂,请使用
def定义普通函数。 -
混淆
map/filter的返回值:nums = [1, 2, 3] # 错误:map 返回的是一个迭代器,直接打印不会显示列表内容 result_map = map(lambda x: x**2, nums) print(result_map) # 输出: <map object at 0x...> # 修正:使用 list() 将其转换为列表 print(list(result_map)) # 输出: [1, 4, 9] -
Lambda 参数数量不匹配:
# 错误:这里 lambda 需要两个参数,但 map 从列表中一次只取出一个 # list(map(lambda x, y: x + y, [1, 2, 3])) # TypeError # 修正:确保 lambda 的参数数量与 map 传入的可迭代对象数量一致 # 如果需要并行处理两个列表,可以使用 zip 或传入多个可迭代对象 list1 = [1, 2, 3] list2 = [10, 20, 30] result = list(map(lambda x, y: x + y, list1, list2)) print(result) # 输出: [11, 22, 33]
6. 小结
- Lambda 表达式:是用于创建匿名简单函数的语法糖。格式为
lambda 参数: 表达式。 - 高阶函数:是接受函数作为参数或返回函数的函数,是函数式编程的基石。
- 核心内置高阶函数:
map(func, iterable):对每个元素应用函数,返回结果迭代器。filter(func, iterable):根据函数的布尔返回值筛选元素。sorted(iterable, key=func):根据 key 函数的返回值进行排序。
- 最佳实践:
lambda适用于简单的、一次性的函数场景。对于复杂的逻辑,请坚持使用def以保证代码的可读性和可维护性。结合使用lambda和map/filter可以让处理序列数据的代码变得非常简洁。