太棒了!欢迎来到 【跟着AI学Python】Python进阶:函数式编程!🎉今天我们将学习如何用 map、filter、reduce 和 生成器表达式 写出更简洁、声明式、无副作用的代码!
💡 函数式编程核心思想:
🎯 今日目标
✅ 掌握 map()、filter()、reduce() 的使用✅ 理解 lambda 表达式 与 普通函数 的选择✅ 用 生成器表达式 替代部分函数式操作✅ 在银行系统中应用函数式风格
📘 一、核心工具速览
| | | |
|---|
map(func, iterable) | | map | |
filter(func, iterable) | | filter | |
functools.reduce(func, iterable) | | | for |
⚠️ 注意:Python 3 中 map/filter 返回迭代器(惰性求值),不是列表!
🔧 二、实践 1:map —— 转换数据
场景:将账户余额格式化为字符串
# 银行账户列表accounts = [ {"name": "Alice", "balance": 1234.56}, {"name": "Bob", "balance": -78.90}, {"name": "Charlie", "balance": 0.0}]# ❌ 传统 for 循环formatted_balances = []for acc in accounts: formatted_balances.append(f"{acc['balance']:.2f} 元")# ✅ 函数式:map + lambdaformatted_balances = list(map( lambda acc: f"{acc['balance']:.2f} 元", accounts))# ✅ 更清晰:定义命名函数def format_balance(acc): return f"{acc['balance']:.2f} 元"formatted_balances = list(map(format_balance, accounts))
✅ 优势:
🔧 三、实践 2:filter —— 筛选数据
场景:找出余额为正的账户
# ❌ 传统方式positive_accounts = []for acc in accounts: if acc["balance"] > 0: positive_accounts.append(acc)# ✅ 函数式:filter + lambdapositive_accounts = list(filter( lambda acc: acc["balance"] > 0, accounts))# ✅ 使用生成器表达式(更 Pythonic!)positive_accounts = [acc for acc in accounts if acc["balance"] > 0]
🔍 何时用 filter vs 列表推导式?
🔧 四、实践 3:reduce —— 累积计算
场景:计算所有账户总余额
from functools import reduce# ❌ 传统循环total = 0for acc in accounts: total += acc["balance"]# ✅ 函数式:reducetotal = reduce( lambda x, y: x + y["balance"], # 累积函数 accounts, # 数据 0 # 初始值)# ✅ 更简单:直接用 sum()(推荐!)total = sum(acc["ance"] for acc in accounts)
⚠️ 重要建议:
- 优先使用内置函数(
sum, max, min, any, all) reduce
🔁 五、函数式 vs 生成器表达式:终极对比
| | | |
|---|
| map(lambda x: x**2, nums) | (x**2 for x in nums) | |
| filter(lambda x: x%2==0, nums) | (x for x in nums if x%2==0) | |
| map(f, filter(p, data)) | (f(x) for x in data if p(x)) | |
📌 Python 之禅:“There should be one obvious way to do it.”→ 生成器表达式通常是更 Pythonic 的选择!
🔧 六、实战:银行系统的函数式重构
原始代码(命令式)
def get_rich_users(accounts, threshold=1000): rich_users = [] for acc in accounts: if acc.balance >= threshold: name_upper = acc.owner.upper() rich_users.append(name_upper) return rich_users
函数式重构
def get_rich_users(accounts, threshold=1000): return list(map( str.upper, map( lambda acc: acc.owner, filter(lambda acc: acc.balance >= threshold, accounts) ) ))# 或更清晰(使用生成器表达式)def get_rich_users(accounts, threshold=1000): return [acc.owner.upper() for acc in accounts if acc.balance >= threshold]
✅ 结果相同,但后者更易读!
🧠 七、高级技巧:函数组合
场景:构建数据处理管道
# 定义处理步骤def to_upper(s): return s.upper()def add_prefix(s): return f"VIP_{s}"# 组合函数def compose(*functions): return lambda x: reduce(lambda acc, f: f(acc), functions, x)# 创建管道pipeline = compose(to_upper, add_prefix)# 应用names = ["alice", "bob"]result = list(map(pipeline, names))print(result) # ['VIP_ALICE', 'VIP_BOB']
🔧 适用场景:ETL(数据抽取-转换-加载)、日志处理
⚠️ 八、函数式的陷阱与建议
❌ 不要过度使用
# 难以理解的嵌套result = reduce(lambda x, y: x + [y*2], filter(lambda z: z>0, map(int, lines)), [])
✅ 推荐做法
- 优先使用生成器表达式(更 Pythonic)
- 复杂逻辑拆分为命名函数
- 用
sum/max/any 替代 reduce - 保持代码可读性第一
📝 小结:函数式编程在 Python 中的定位
Python 不是纯函数式语言,但支持函数式风格
最佳实践:
- ✅ 用 生成器表达式 替代简单
map/filter - ✅ 用 内置函数(
sum, max)替代 reduce
🎉 恭喜完成函数式编程进阶!你已掌握让代码更简洁、更优雅的强大工具!
继续加油,你的代码正在变得越来越 Pythonic!🐍✨