
大家好,我是煜道。
今天我们一起来学习 函数式编程——lambda、map、reduce与装饰器。
引言
函数式编程是一种编程范式,它将计算视为函数的求值,强调使用纯函数、避免副作用和不可变性。 Python虽然不是纯粹的函数式语言,但它支持多种函数式编程特性,包括lambda表达式、高阶函数、闭包、装饰器等。这些特性使得Python代码更加简洁、表达力更强。
本文将系统介绍Python函数式编程的核心概念,包括lambda表达式、map、filter、reduce等高阶函数,以及装饰器的深入应用。通过本文的学习,我们将能够在实际开发中灵活运用这些函数式编程技巧,写出更加优雅的Python代码。

01 lambda表达式
1.1 lambda的基本语法
lambda表达式用于创建简短的匿名函数:
# 完整函数定义defadd(a, b):return a + b# lambda表达式add_lambda = lambda a, b: a + bprint(add(2, 3)) # 5print(add_lambda(2, 3)) # 5# lambda语法# lambda parameters: expression
1.2 lambda的限制
lambda表达式只能包含一个表达式,不能包含语句:
# 有效lambdasquare = lambda x: x ** 2print(square(5)) # 25# 无效lambda(包含语句)# lambda x: print(x) # 语法错误# 替代方案defprint_square(x): print(x ** 2)
1.3 lambda的使用场景
# 1. 高阶函数的参数numbers = [1, 2, 3, 4, 5]squared = list(map(lambda x: x ** 2, numbers))print(squared) # [1, 4, 9, 16, 25]# 2. 排序keystudents = [("Alice", 25), ("Bob", 20), ("Charlie", 25)]students.sort(key=lambda x: x[1]) # 按年龄排序print(students) # [('Bob', 20), ('Alice', 25), ('Charlie', 25)]# 3. 条件返回值max_val = lambda a, b: a if a > b else bprint(max_val(10, 20)) # 20

02 map函数
2.1 map的基本用法
map()将函数应用于可迭代对象的每个元素:
# 基本语法# map(function, iterable, ...)numbers = [1, 2, 3, 4, 5]# 计算平方squares = list(map(lambda x: x ** 2, numbers))print(squares) # [1, 4, 9, 16, 25]# 转换类型strings = ["1", "2", "3"]ints = list(map(int, strings))print(ints) # [1, 2, 3]
2.2 多参数map
# 处理多个可迭代对象list1 = [1, 2, 3]list2 = [4, 5, 6]# 对应元素相乘products = list(map(lambda x, y: x * y, list1, list2))print(products) # [4, 10, 18]# 以最短列表为准print(list(map(lambda x, y: f"({x}, {y})", list1, list2)))# ['(1, 4)', '(2, 5)', '(3, 6)']
2.3 map与列表推导式
numbers = [1, 2, 3, 4, 5]# map实现squares = list(map(lambda x: x ** 2, numbers))# 列表推导式(更直观)squares2 = [x ** 2for x in numbers]print(squares == squares2) # True


03 filter函数
3.1 filter的基本用法
filter()过滤可迭代对象,只保留使函数返回True的元素:
# 基本语法# filter(function, iterable)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]# 过滤空值values = [0, 1, "", "hello", None, [], [1, 2]]truthy = list(filter(None, values)) # 过滤假值print(truthy) # [1, 'hello', [1, 2]]
3.2 filter与列表推导式
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]# filter实现evens = list(filter(lambda x: x % 2 == 0, numbers))# 列表推导式(带条件)evens2 = [x for x in numbers if x % 2 == 0]print(evens == evens2) # True
3.3 实际应用
# 过滤无效数据data = ["", "text", None, " ", "valid", 0, 1, []]# 过滤空字符串和空白valid_items = list(filter(lambda x: x and (not isinstance(x, str) or x.strip()), data))print(valid_items) # ['text', 'valid', 1]

04 reduce函数
4.1 reduce的基本用法
reduce()对可迭代对象的元素进行累积计算:
from functools import reducenumbers = [1, 2, 3, 4, 5]# 累加total = reduce(lambda x, y: x + y, numbers)print(total) # 15# 初始值total_with_init = reduce(lambda x, y: x + y, numbers, 10)print(total_with_init) # 25
4.2 累积计算过程

4.3 常见应用
from functools import reduce# 求积numbers = [1, 2, 3, 4, 5]product = reduce(lambda x, y: x * y, numbers)print(product) # 120# 连接字符串words = ["Hello", " ", "World", "!"]sentence = reduce(lambda x, y: x + y, words)print(sentence) # "Hello World!"# 最大值numbers = [3, 1, 4, 1, 5, 9, 2, 6]max_val = reduce(lambda a, b: a if a > b else b, numbers)print(max_val) # 9# 分组(字典归约)from collections import defaultdictdata = [("a", 1), ("b", 2), ("a", 3), ("b", 1)]grouped = reduce(lambda acc, pair: {**acc, pair[0]: acc.get(pair[0], 0) + pair[1]}, data, {})print(grouped) # {'a': 4, 'b': 3}

05 偏函数
5.1 partial
functools.partial创建函数的预设参数版本:
from functools import partial# 基本用法defmultiply(a, b):return a * b# 创建偏函数double = partial(multiply, 2)triple = partial(multiply, 3)print(double(5)) # 10print(triple(5)) # 15# 与map配合numbers = [1, 2, 3, 4, 5]doubled = list(map(double, numbers))print(doubled) # [2, 4, 6, 8, 10]
5.2 实际应用
from functools import partial# 配置函数defconfigure_app(app, host="localhost", port=8080, debug=False): print(f"Configuring {app} at {host}:{port}, debug={debug}")return (app, host, port, debug)# 创建不同配置dev_config = partial(configure_app, host="0.0.0.0", port=3000, debug=True)prod_config = partial(configure_app, host="0.0.0.0", port=8080, debug=False)print(dev_config("MyApp")) # ('MyApp', '0.0.0.0', 3000, True)print(prod_config("MyApp")) # ('MyApp', '0.0.0.0', 8080, False)

06 装饰器深入
6.1 函数式装饰器
import functoolsimport timedeftimer(func):"""计算函数执行时间""" @functools.wraps(func)defwrapper(*args, **kwargs): start = time.time() result = func(*args, **kwargs) end = time.time() print(f"{func.__name__} took {end - start:.4f} seconds")return resultreturn wrapper@timerdefslow_function(): time.sleep(0.5)return"Done"result = slow_function()
6.2 带参数的装饰器
import functoolsdefrepeat(times):"""重复执行函数"""defdecorator(func): @functools.wraps(func)defwrapper(*args, **kwargs): results = []for _ in range(times): results.append(func(*args, **kwargs))return resultsreturn wrapperreturn decorator@repeat(3)defgreet(name):returnf"Hello, {name}!"print(greet("World"))# ['Hello, World!', 'Hello, World!', 'Hello, World!']
6.3 类装饰器
import functoolsclassCountCalls:"""统计函数调用次数"""def__init__(self, func): self.func = func self.count = 0 functools.update_wrapper(self, func)def__call__(self, *args, **kwargs): self.count += 1 print(f"{self.func.__name__} called {self.count} times")return self.func(*args, **kwargs)@CountCallsdefexample():return"example"example()example()example()# example called 1 times# example called 2 times# example called 3 times
6.4 堆叠装饰器
import functoolsdefuppercase(func): @functools.wraps(func)defwrapper(*args, **kwargs):return func(*args, **kwargs).upper()return wrapperdefexclamation(func): @functools.wraps(func)defwrapper(*args, **kwargs):return func(*args, **kwargs) + "!"return wrapper# 装饰器从下到上应用@uppercase@exclamationdefgreet(name):returnf"Hello, {name}"print(greet("World")) # HELLO, WORLD!!

6.5 常见装饰器模式
import functools# 缓存装饰器defcache(func): cache_dict = {} @functools.wraps(func)defwrapper(*args):if args in cache_dict:return cache_dict[args] result = func(*args) cache_dict[args] = resultreturn resultreturn wrapper# 验证装饰器defvalidate_args(**types):defdecorator(func): @functools.wraps(func)defwrapper(*args):for i, (arg, expected) in enumerate(zip(args, types.values())):ifnot isinstance(arg, expected):raise TypeError(f"Argument {i} must be {expected.__name__}")return func(*args)return wrapperreturn decorator# 日志装饰器deflog_calls(func): @functools.wraps(func)defwrapper(*args, **kwargs): print(f"Calling {func.__name__} with args={args}, kwargs={kwargs}") result = func(*args, **kwargs) print(f"{func.__name__} returned {result}")return resultreturn wrapper

07 函数式编程实践
7.1 管道式编程
from functools import reducedefpipe(*functions):"""管道函数组合"""defcompose(f, g):returnlambda x: g(f(x))return reduce(compose, functions, lambda x: x)defadd_one(x):return x + 1defdouble(x):return x * 2defsquare(x):return x ** 2# 创建管道pipeline = pipe(add_one, double, square)result = pipeline(5)print(result) # ((5+1)*2)^2 = 144
7.2 函数组合工具
from functools import reducedefcompose(*functions):"""组合多个函数"""defcompose_two(f, g):returnlambda x: f(g(x))return reduce(compose_two, functions, lambda x: x)# 使用f = compose(lambda x: x * 2,lambda x: x + 1,lambda x: x ** 2)print(f(5)) # ((5)^2 + 1) * 2 = 52
7.3 柯里化
defcurry(func):"""柯里化转换"""defcurried(*args):if len(args) == func.__code__.co_argcount:return func(*args)returnlambda *more: curried(*(args + more))return curried@currydefadd(a, b, c):return a + b + c# 部分应用add_5 = add(5)print(add_5(3, 2)) # 10print(add(1)(2)(3)) # 6

08 小结
本文介绍了Python函数式编程的核心概念:
函数式编程技巧使Python代码更加简洁和表达力强。在实际开发中,应根据场景选择合适的编程范式,灵活运用这些工具可以提高代码质量。
