Python函数式编程

一、 简介

Python 函数式编程是一种编程范式,它强调使用纯函数、避免状态变化和可变数据。以下是 Python 函数式编程的详细讲解:

  1. 核心概念
    纯函数
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] - 新列表
  1. 高阶函数
    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
  1. 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}]
  1. 函数组合和柯里化
    函数组合
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
  1. 递归代替循环
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
  1. 列表推导式和生成器表达式
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]
  1. 常用函数式工具
    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
  1. 实际应用示例
    数据处理管道
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 不是纯函数式语言,要合理使用

递归深度限制(可使用尾递归优化或迭代)

性能考虑:某些函数式操作可能比命令式慢

相关推荐
周杰伦fans1 小时前
在C#中,`StringContent` 是 `HttpContent` 的一个派生类
开发语言·数据库·c#
DanB241 小时前
Java(多线程)
java·开发语言·python
O***p6041 小时前
Java在分布式中的Archaius
java·开发语言·分布式
在繁华处1 小时前
JAVA实战:文件管理系统1.0
java·开发语言·前端
算法与编程之美1 小时前
Java数组动态扩容
java·开发语言·python·算法
weixin_462446231 小时前
【原创实践】python版playwright截取多个图
开发语言·python·策略模式
JienDa2 小时前
JienDa聊PHP:算命平台实战中主流PHP框架的协同架构方略
开发语言·架构·php
2301_764441332 小时前
三维建筑非法入侵情景推演
python·学习·算法
爱写代码的小朋友2 小时前
21天学通Python全栈开发实战指南
开发语言·python