Lambda 函数与函数式编程
简洁的匿名函数 —— 一行代码解决问题
什么是 Lambda 函数?
Lambda 函数是匿名函数(没有名字的函数),用于简单的一次性操作。
语法:
python
lambda 参数: 表达式对比:
python
# 普通函数
def square(x):
return x ** 2
# Lambda 函数(等价)
square = lambda x: x ** 2
print(square(5)) # 25基本用法
示例 1:简单运算
python
# 加法
add = lambda x, y: x + y
print(add(3, 5)) # 8
# BMI 计算
bmi = lambda weight, height: weight / (height ** 2)
print(bmi(70, 1.75)) # 22.86
# 判断成年
is_adult = lambda age: age >= 18
print(is_adult(25)) # True示例 2:与内置函数配合
python
# sorted() + lambda
students = [
{'name': 'Alice', 'age': 25, 'gpa': 3.8},
{'name': 'Bob', 'age': 22, 'gpa': 3.5},
{'name': 'Carol', 'age': 24, 'gpa': 3.9}
]
# 按 GPA 排序
sorted_by_gpa = sorted(students, key=lambda s: s['gpa'], reverse=True)
for s in sorted_by_gpa:
print(f"{s['name']}: {s['gpa']}")
# 按年龄排序
sorted_by_age = sorted(students, key=lambda s: s['age'])map()、filter()、reduce()
1. map():对每个元素应用函数
python
# 普通方式
incomes = [50000, 60000, 75000, 80000]
incomes_after_tax = []
for income in incomes:
incomes_after_tax.append(income * 0.75)
# 使用 map + lambda
incomes_after_tax = list(map(lambda x: x * 0.75, incomes))
print(incomes_after_tax) # [37500, 45000, 56250, 60000]
# 列表推导式(更 Pythonic)
incomes_after_tax = [x * 0.75 for x in incomes]社科应用:
python
# 收入对数转换
import math
incomes = [45000, 60000, 75000, 90000]
log_incomes = list(map(lambda x: math.log(x), incomes))
# 标准化分数
scores = [85, 92, 78, 88]
mean = sum(scores) / len(scores)
std_scores = list(map(lambda x: (x - mean) / 10, scores))2. filter():筛选元素
python
ages = [18, 25, 16, 30, 15, 40, 12, 35]
# 筛选成年人
adults = list(filter(lambda age: age >= 18, ages))
print(adults) # [18, 25, 30, 40, 35]
# 筛选高收入者
incomes = [45000, 75000, 120000, 55000, 95000]
high_earners = list(filter(lambda x: x > 70000, incomes))
print(high_earners) # [75000, 120000, 95000]
# 列表推导式(更推荐)
adults = [age for age in ages if age >= 18]3. reduce():累积计算
python
from functools import reduce
# 计算乘积
numbers = [1, 2, 3, 4, 5]
product = reduce(lambda x, y: x * y, numbers)
print(product) # 120
# 找最大值
scores = [85, 92, 78, 95, 88]
max_score = reduce(lambda a, b: a if a > b else b, scores)
print(max_score) # 95
# 但更好的方式是用内置函数
max_score = max(scores)实战案例
案例 1:数据清洗流水线
python
# 原始数据
raw_incomes = [50000, -1000, 75000, 0, 120000, 9999999, 60000]
# 清洗流水线
clean_incomes = list(
filter(lambda x: 0 < x < 1000000, # 筛选有效值
map(lambda x: round(x, -3), # 四舍五入到千位
raw_incomes))
)
print(clean_incomes) # [50000, 75000, 120000, 60000]案例 2:按多个条件排序
python
respondents = [
{'id': 1, 'age': 30, 'income': 75000},
{'id': 2, 'age': 25, 'income': 85000},
{'id': 3, 'age': 25, 'income': 70000},
{'id': 4, 'age': 30, 'income': 90000}
]
# 先按年龄,再按收入排序
sorted_data = sorted(respondents, key=lambda r: (r['age'], r['income']))
for r in sorted_data:
print(f"ID{r['id']}: {r['age']}岁, ${r['income']:,}")案例 3:动态生成函数
python
def make_multiplier(n):
"""返回一个乘以 n 的函数"""
return lambda x: x * n
# 创建不同的倍数函数
double = make_multiplier(2)
triple = make_multiplier(3)
multiply_by_10 = make_multiplier(10)
print(double(5)) # 10
print(triple(5)) # 15
print(multiply_by_10(5)) # 50
# 应用:不同的税率计算器
def make_tax_calculator(rate):
return lambda income: income * rate
tax_low = make_tax_calculator(0.10)
tax_mid = make_tax_calculator(0.20)
tax_high = make_tax_calculator(0.30)
income = 100000
print(f"低税率: ${tax_low(income):,.0f}")
print(f"中税率: ${tax_mid(income):,.0f}")
print(f"高税率: ${tax_high(income):,.0f}")Lambda vs 普通函数
| 特性 | Lambda | 普通函数 |
|---|---|---|
| 语法 | lambda x: x**2 | def f(x): return x**2 |
| 名称 | 匿名 | 有名称 |
| 复杂度 | 单行表达式 | 可多行 |
| 文档 | 无法添加 | 可添加文档字符串 |
| 适用场景 | 简单、一次性 | 复杂、可复用 |
何时用 Lambda?
- 简单的一次性操作
- 作为参数传递(
sorted(key=...)) - map/filter 中的简单逻辑
何时用普通函数?
- 逻辑复杂(多行代码)
- 需要文档说明
- 需要复用
列表推导式 vs Lambda
对于大多数情况,列表推导式比 lambda 更 Pythonic:
python
numbers = [1, 2, 3, 4, 5]
# 使用 map + lambda
squares = list(map(lambda x: x**2, numbers))
# 使用列表推导式(更好)
squares = [x**2 for x in numbers]
# 使用 filter + lambda
evens = list(filter(lambda x: x % 2 == 0, numbers))
# 使用列表推导式(更好)
evens = [x for x in numbers if x % 2 == 0]常见陷阱
陷阱 1:闭包中的变量绑定
python
# 错误示例
functions = []
for i in range(3):
functions.append(lambda x: x + i)
print(functions[0](10)) # 期望12,实际12
print(functions[1](10)) # 期望11,实际12
print(functions[2](10)) # 期望12,实际12
# 所有函数都使用最后的 i 值(2)
# 正确做法:使用默认参数
functions = []
for i in range(3):
functions.append(lambda x, i=i: x + i)
print(functions[0](10)) # 10
print(functions[1](10)) # 11
print(functions[2](10)) # 12陷阱 2:过度使用导致代码难读
python
# 难以理解
result = list(filter(lambda x: x[1] > 50000 and x[2] < 40,
map(lambda p: (p['name'], p['income'], p['age']),
[r for r in data if r['gender'] == 'M'])))
# 清晰的方式
male_respondents = [r for r in data if r['gender'] == 'M']
high_income_young = [
(r['name'], r['income'], r['age'])
for r in male_respondents
if r['income'] > 50000 and r['age'] < 40
]练习题
练习 1:使用 Lambda 排序
python
students = [
('Alice', 25, 3.8),
('Bob', 22, 3.5),
('Carol', 24, 3.9),
('David', 23, 3.6)
]
# 任务:按以下方式排序
# 1. 按 GPA 从高到低
# 2. 按年龄从小到大
# 3. 按名字字母顺序练习 2:数据转换
python
incomes = [45000, 60000, 75000, 90000, 120000]
# 使用 map + lambda:
# 1. 计算税后收入(税率25%)
# 2. 转换为万元(除以10000)
# 3. 保留1位小数练习 3:综合应用
python
data = [
{'name': 'Alice', 'age': 25, 'score': 85},
{'name': 'Bob', 'age': 30, 'score': 55},
{'name': 'Carol', 'age': 28, 'score': 92},
{'name': 'David', 'age': 22, 'score': 78}
]
# 任务:
# 1. 筛选出及格的学生(score >= 60)
# 2. 按分数从高到低排序
# 3. 只保留姓名和分数下一步
在下一节中,我们将学习 模块与包管理,了解如何组织和导入代码。
继续!