一、 简介
Python 函数式编程是一种编程范式,它强调使用纯函数、避免状态变化和可变数据。以下是 Python 函数式编程的详细讲解:
- 核心概念
纯函数
python
# 纯函数:相同输入总是产生相同输出,无副作用
def pure_multiply(x, y):
return x * y
# 非纯函数:有副作用
result = 0
def impure_multiply(x, y):
global result
result = x * y # 修改了外部状态
return result
不可变性
python
# 使用不可变数据结构
# 不好的做法(可变)
def add_to_list(lst, item):
lst.append(item) # 修改了原列表
return lst
# 好的做法(不可变)
def add_to_list_immutable(lst, item):
return lst + [item] # 返回新列表
my_list = [1, 2, 3]
new_list = add_to_list_immutable(my_list, 4)
print(my_list) # [1, 2, 3] - 原列表未改变
print(new_list) # [1, 2, 3, 4] - 新列表
- 高阶函数
map() - 映射
python
# 对每个元素应用函数
numbers = [1, 2, 3, 4, 5]
# 使用 map
squared = list(map(lambda x: x ** 2, numbers))
print(squared) # [1, 4, 9, 16, 25]
# 等价于列表推导式
squared_comp = [x ** 2 for x in numbers]
# 使用具名函数
def square(x):
return x ** 2
squared_named = list(map(square, numbers))
filter() - 过滤
python
# 过滤满足条件的元素
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# 过滤偶数
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(evens) # [2, 4, 6, 8, 10]
# 过滤大于5的数
large_numbers = list(filter(lambda x: x > 5, numbers))
print(large_numbers) # [6, 7, 8, 9, 10]
# 使用具名函数
def is_positive(x):
return x > 0
positives = list(filter(is_positive, [-2, -1, 0, 1, 2]))
print(positives) # [1, 2]
reduce() - 归约
python
from functools import reduce
numbers = [1, 2, 3, 4, 5]
# 计算乘积
product = reduce(lambda x, y: x * y, numbers)
print(product) # 120
# 计算最大值
max_num = reduce(lambda x, y: x if x > y else y, numbers)
print(max_num) # 5
# 拼接字符串
words = ['Hello', 'World', 'Python']
sentence = reduce(lambda x, y: x + ' ' + y, words)
print(sentence) # Hello World Python
- lambda函数
python
# 匿名函数,用于简单的操作
add = lambda x, y: x + y
print(add(3, 5)) # 8
# 在排序中使用
students = [
{'name': 'Alice', 'score': 85},
{'name': 'Bob', 'score': 92},
{'name': 'Charlie', 'score': 78}
]
# 按分数排序
sorted_students = sorted(students, key=lambda x: x['score'])
print(sorted_students)
# [{'name': 'Charlie', 'score': 78}, {'name': 'Alice', 'score': 85}, {'name': 'Bob', 'score': 92}]
- 函数组合和柯里化
函数组合
python
def compose(f, g):
return lambda x: f(g(x))
def add_one(x):
return x + 1
def multiply_by_two(x):
return x * 2
# 组合函数:先加1,再乘2
add_then_multiply = compose(multiply_by_two, add_one)
print(add_then_multiply(3)) # (3 + 1) * 2 = 8
柯里化
python
from functools import partial
# 柯里化:将多参数函数转换为一系列单参数函数
def multiply(x, y):
return x * y
# 创建固定第一个参数的函数
double = partial(multiply, 2)
triple = partial(multiply, 3)
print(double(5)) # 10
print(triple(5)) # 15
# 手动柯里化
def curry_multiply(x):
def multiply_y(y):
return x * y
return multiply_y
double_manual = curry_multiply(2)
print(double_manual(5)) # 10
- 递归代替循环
python
# 使用递归代替循环
def factorial(n):
if n == 0:
return 1
else:
return n * factorial(n - 1)
print(factorial(5)) # 120
# 递归处理列表
def sum_list(lst):
if not lst:
return 0
else:
return lst[0] + sum_list(lst[1:])
print(sum_list([1, 2, 3, 4, 5])) # 15
- 列表推导式和生成器表达式
python
# 函数式风格的列表操作
numbers = [1, 2, 3, 4, 5]
# 列表推导式 (更Pythonic的方式)
squares = [x ** 2 for x in numbers]
evens = [x for x in numbers if x % 2 == 0]
print(squares) # [1, 4, 9, 16, 25]
print(evens) # [2, 4]
# 生成器表达式 (惰性求值)
squares_gen = (x ** 2 for x in numbers)
print(list(squares_gen)) # [1, 4, 9, 16, 25]
- 常用函数式工具
itertools 模块
python
import itertools
# 无限迭代器
counter = itertools.count(start=1, step=2)
print([next(counter) for _ in range(5)]) # [1, 3, 5, 7, 9]
# 排列组合
letters = ['A', 'B', 'C']
combinations = list(itertools.combinations(letters, 2))
permutations = list(itertools.permutations(letters, 2))
print(combinations) # [('A', 'B'), ('A', 'C'), ('B', 'C')]
print(permutations) # [('A', 'B'), ('A', 'C'), ('B', 'A'), ('B', 'C'), ('C', 'A'), ('C', 'B')]
functools 模块
python
from functools import lru_cache, partial, reduce
# 记忆化装饰器
@lru_cache(maxsize=None)
def fibonacci(n):
if n < 2:
return n
return fibonacci(n-1) + fibonacci(n-2)
print(fibonacci(10)) # 55
- 实际应用示例
数据处理管道
python
from functools import reduce
data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# 函数式数据处理管道
result = reduce(
lambda acc, x: acc + x,
map(
lambda x: x * 2,
filter(
lambda x: x % 2 == 0,
data
)
),
0 # 初始值
)
print(result) # 60 (2*2 + 4*2 + 6*2 + 8*2 + 10*2)
# 更清晰的写法
even_numbers = filter(lambda x: x % 2 == 0, data)
doubled = map(lambda x: x * 2, even_numbers)
sum_result = reduce(lambda acc, x: acc + x, doubled, 0)
print(sum_result) # 60
配置处理
python
from functools import reduce
configs = [
{'theme': 'dark', 'font_size': 12},
{'theme': 'light', 'language': 'en'},
{'font_size': 14, 'language': 'zh'}
]
# 合并配置字典
def merge_dicts(dict1, dict2):
return {**dict1, **dict2}
final_config = reduce(merge_dicts, configs, {})
print(final_config)
# {'theme': 'light', 'font_size': 14, 'language': 'zh'}
二、优点和注意事项
优点:
代码更简洁、可读性更强
易于测试和调试
更好的并发支持
减少副作用带来的bug
注意事项:
Python 不是纯函数式语言,要合理使用
递归深度限制(可使用尾递归优化或迭代)
性能考虑:某些函数式操作可能比命令式慢