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. 组合优于继承
相关推荐
2501_940943912 小时前
体系课\ Python Web全栈工程师
开发语言·前端·python
田姐姐tmner2 小时前
Python切片
开发语言·python
t***31652 小时前
爬虫学习案例3
爬虫·python·学习
AI小云3 小时前
【数据操作与可视化】Pandas数据处理-其他操作
python·pandas
大佬,救命!!!3 小时前
更换适配python版本直接进行机器学习深度学习等相关环境配置(非仿真环境)
人工智能·python·深度学习·机器学习·学习笔记·详细配置
无心水4 小时前
【Python实战进阶】4、Python字典与集合深度解析
开发语言·人工智能·python·python字典·python集合·python实战进阶·python工业化实战进阶
上班职业摸鱼人4 小时前
python文件中导入另外一个模块这个模块
python
永远是夏天4 小时前
Python面向对象编程(OOP)全教程:从入门到实战(附案例)
python
动感小麦兜4 小时前
服务器搭建
linux·服务器·python