Python函数式编程:优雅的代码艺术

想象一下,如果编程就像搭积木一样,通过组合简单的模块来构建复杂的功能,而不是编写冗长的指令序列。这正是函数式编程的魅力所在!它不仅仅是一种技术,更是一种思维方式,让代码变得更简洁、更可预测、更易于理解。

函数式编程的核心理念

  • 不变性:数据的安全保障
  • 纯函数:相同的输入,永远得到相同的输出
  • 函数是最重要的

实战代码:函数式编程的实践

基础函数式操作

python 复制代码
# 传统方式 vs 函数式方式

# 传统命令式编程
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# 筛选偶数并计算平方
result_imperative = []
for num in numbers:
    if num % 2 == 0:
        result_imperative.append(num ** 2)

print(f"命令式结果: {result_imperative}")

# 函数式编程方式
result_functional = list(map(lambda x: x ** 2, 
                           filter(lambda x: x % 2 == 0, numbers)))

print(f"函数式结果: {result_functional}")

# 更清晰的写法(使用生成器表达式)
result_clear = [x ** 2 for x in numbers if x % 2 == 0]
print(f"清晰写法: {result_clear}")

高阶函数应用

python 复制代码
from functools import reduce
from typing import List, Callable

def compose(*functions: Callable) -> Callable:
    """函数组合:将多个函数组合成一个新函数"""
    def composed(arg):
        result = arg
        for func in reversed(functions):
            result = func(result)
        return result
    return composed

def pipe(*functions: Callable) -> Callable:
    """管道操作:从左到右执行函数序列"""
    def piped(arg):
        result = arg
        for func in functions:
            result = func(result)
        return result
    return piped

# 创建一些小的纯函数
def add(x: int) -> Callable[[int], int]:
    """柯里化的加法函数"""
    return lambda y: x + y

def multiply(x: int) -> Callable[[int], int]:
    """柯里化的乘法函数"""
    return lambda y: x * y

def filter_even(numbers: List[int]) -> List[int]:
    """筛选偶数"""
    return list(filter(lambda x: x % 2 == 0, numbers))

def square_all(numbers: List[int]) -> List[int]:
    """对所有数字求平方"""
    return list(map(lambda x: x ** 2, numbers))

def sum_all(numbers: List[int]) -> int:
    """求和"""
    return reduce(lambda x, y: x + y, numbers, 0)

# 使用函数组合构建复杂操作
process_numbers = pipe(
    filter_even,    # 第一步:筛选偶数
    square_all,     # 第二步:求平方
    sum_all         # 第三步:求和
)

# 测试函数组合
numbers = [1, 2, 3, 4, 5, 6]
result = process_numbers(numbers)
print(f"处理结果: {result}")  # 4 + 16 + 36 = 56

# 柯里化函数的使用
add_five = add(5)
multiply_by_three = multiply(3)

print(f"5 + 10 = {add_five(10)}")
print(f"3 × 7 = {multiply_by_three(7)}")

# 组合柯里化函数
add_then_multiply = compose(multiply_by_three, add_five)
print(f"(5 + 10) × 3 = {add_then_multiply(10)}")

不可变数据结构

python 复制代码
from typing import Dict, List, Any
from copy import deepcopy

def update_in(data: Dict, keys: List, value: Any) -> Dict:
    """不可变地更新嵌套字典的特定路径"""
    if len(keys) == 0:
        return value
    
    key = keys[0]
    remaining_keys = keys[1:]
    
    # 创建数据的深拷贝
    new_data = deepcopy(data)
    
    if isinstance(new_data, dict):
        if key in new_data:
            new_data[key] = update_in(new_data[key], remaining_keys, value)
        else:
            new_data[key] = update_in({}, remaining_keys, value)
    else:
        # 如果不是字典,创建新的字典结构
        new_data = {key: update_in({}, remaining_keys, value)}
    
    return new_data

def assoc(data: Dict, key: str, value: Any) -> Dict:
    """不可变地设置字典键值"""
    new_data = data.copy()
    new_data[key] = value
    return new_data

def dissoc(data: Dict, key: str) -> Dict:
    """不可变地删除字典键"""
    new_data = data.copy()
    if key in new_data:
        del new_data[key]
    return new_data

# 使用不可变数据操作
user_data = {
    "name": "张三",
    "age": 25,
    "address": {
        "city": "北京",
        "street": "朝阳路"
    },
    "hobbies": ["阅读", "编程"]
}

print("原始数据:", user_data)

# 不可变更新
new_user = assoc(user_data, "age", 26)
print("更新年龄后:", new_user)
print("原始数据未改变:", user_data["age"])

# 删除属性
user_without_age = dissoc(user_data, "age")
print("删除年龄后:", user_without_age)

# 深层更新
updated_user = update_in(user_data, ["address", "city"], "上海")
print("更新城市后:", updated_user)
print("原始地址未改变:", user_data["address"]["city"])

函数式数据处理

python 复制代码
from functools import partial
from operator import itemgetter, attrgetter

class Product:
    def __init__(self, name: str, price: float, category: str):
        self.name = name
        self.price = price
        self.category = category
    
    def __repr__(self):
        return f"Product({self.name}, ${self.price}, {self.category})"

# 创建产品列表
products = [
    Product("笔记本电脑", 5999, "电子产品"),
    Product("智能手机", 3999, "电子产品"),
    Product("书籍", 49, "文教用品"),
    Product("咖啡", 35, "食品饮料"),
    Product("鼠标", 89, "电子产品"),
    Product("笔记本", 15, "文教用品")
]

# 函数式数据处理管道
def create_data_pipeline(*transformations):
    """创建数据处理管道"""
    def pipeline(data):
        return reduce(lambda d, transform: transform(d), 
                     transformations, data)
    return pipeline

# 各种数据处理函数
def filter_by_category(category: str):
    """按类别筛选的柯里化函数"""
    return partial(filter, lambda p: p.category == category)

def filter_by_price(max_price: float):
    """按价格筛选的柯里化函数"""
    return partial(filter, lambda p: p.price <= max_price)

def sort_by_price(descending: bool = False):
    """按价格排序的柯里化函数"""
    return partial(sorted, key=attrgetter('price'), reverse=descending)

def get_names():
    """提取产品名称"""
    return partial(map, attrgetter('name'))

def calculate_total_price():
    """计算总价格"""
    return partial(reduce, lambda total, p: total + p.price)

# 构建复杂的数据处理管道
affordable_electronics = create_data_pipeline(
    filter_by_category("电子产品"),
    filter_by_price(5000),
    sort_by_price(descending=True)
)

cheap_product_names = create_data_pipeline(
    filter_by_price(100),
    get_names(),
    list
)

total_electronics_price = create_data_pipeline(
    filter_by_category("电子产品"),
    calculate_total_price()
)

# 使用数据处理管道
print("实惠的电子产品:")
for product in affordable_electronics(products):
    print(f"  {product}")

print(f"\n便宜商品名称: {list(cheap_product_names(products))}")

# 注意:calculate_total_price 返回的是reduce函数,需要传入初始值0
electronics_price = total_electronics_price(products)(0)
print(f"电子产品总价: ${electronics_price}")

递归和惰性求值

python 复制代码
from itertools import islice

def fibonacci():
    """生成无限斐波那契数列(惰性求值)"""
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a + b

def recursive_sum(numbers: List[int]) -> int:
    """递归方式求和"""
    if not numbers:
        return 0
    return numbers[0] + recursive_sum(numbers[1:])

def recursive_max(numbers: List[int]) -> int:
    """递归方式求最大值"""
    if len(numbers) == 1:
        return numbers[0]
    
    rest_max = recursive_max(numbers[1:])
    return numbers[0] if numbers[0] > rest_max else rest_max

def trampoline(func):
    """蹦床函数:优化递归,防止栈溢出"""
    def trampolined(*args, **kwargs):
        result = func(*args, **kwargs)
        while callable(result):
            result = result()
        return result
    return trampolined

# 使用惰性序列
print("斐波那契数列前10项:")
fib_sequence = islice(fibonacci(), 10)
print(list(fib_sequence))

# 使用递归函数
numbers = [1, 5, 3, 9, 2]
print(f"递归求和: {recursive_sum(numbers)}")
print(f"递归求最大值: {recursive_max(numbers)}")

# 记忆化装饰器(缓存函数结果)
def memoize(func):
    """记忆化装饰器:缓存函数计算结果"""
    cache = {}
    
    def memoized(*args):
        if args in cache:
            return cache[args]
        result = func(*args)
        cache[args] = result
        return result
    
    return memoized

@memoize
def factorial(n: int) -> int:
    """记忆化的阶乘函数"""
    if n <= 1:
        return 1
    return n * factorial(n - 1)

print(f"\n记忆化阶乘:")
print(f"5! = {factorial(5)}")
print(f"10! = {factorial(10)}")
# 第二次调用会使用缓存
print(f"5! (缓存) = {factorial(5)}")

函数式编程原则

  1. 纯函数优先
  2. 不可变性原则
  3. 声明式编程
  4. 组合优于继承
相关推荐
傲笑风4 小时前
【openvino】tinybert基于openvino服务化部署(四)
人工智能·python·自然语言处理·nlp·bert·openvino
维基框架4 小时前
WIKI 知识库 v1.1.1 正式发布
人工智能·python
谢白羽8 小时前
SGLang的AWQ量化笔记
笔记·python·sglang
迷迭香yy8 小时前
基金档案数据工程实战从收入分析到持仓穿透的Python解析 IG50免费开源股票数据API接口
开发语言·python
清水白石0088 小时前
Python 类型设计深度解析:TypedDict 能否替代 dataclass?从 JSON 数据边界到 API 设计的最佳实践
java·python·json
️学习的小王9 小时前
Git项目提交忽略文件怎么做?以Python项目为例,详解.gitignore
git·python·elasticsearch
前端 贾公子9 小时前
第09章:上下文与记忆 (6)
开发语言·前端·python
evans在进步9 小时前
Java 常用设计模式入门:建造者、工厂、单例、外观与代理
java·python·设计模式
jayson.h10 小时前
PDF 合并+添加页码 相关库、类、函数
开发语言·前端·python
典典分享指南10 小时前
用飞书多维表格搭建内容管理看板
java·python·r语言·composer·symfony