从入门到高级详解Python中reduce()函数的使用
一、开篇:从"逐个处理"到"累积计算"
map()对序列中的每个元素应用同一个操作,filter()从序列中筛选出符合条件的元素。而reduce()的思路完全不同——它将序列中的元素两两聚合,最终"累积"成一个结果。
用一个简单例子理解reduce的思维:
from functools import reduce # 问题:计算 [1, 2, 3, 4, 5] 的累加和 numbers = [1, 2, 3, 4, 5] # reduce的累积过程: # 第1步:1 + 2 = 3 # 第2步:3 + 3 = 6 # 第3步:6 + 4 = 10 # 第4步:10 + 5 = 15 # 结果:15 result = reduce(lambda a, b: a + b, numbers) print(result) # 15 # 等价于: # ((((1 + 2) + 3) + 4) + 5) = 15
reduce()像一个"滚雪球"的过程——从第一个元素开始,依次将累积结果与下一个元素进行计算,最终得到一个汇总值。
二、reduce()的基本用法
2.1 语法和工作原理
from functools import reduce
# reduce(function, iterable[, initializer])
# function: 二元函数,接收两个参数(累积值, 下一个元素),返回新的累积值
# iterable: 可迭代对象
# initializer: 可选,初始累积值
# 工作原理图解:
# 没有initializer时:
# 累积值 = 第一个元素
# for 每个剩余元素:
# 累积值 = function(累积值, 当前元素)
# return 累积值
# 有initializer时:
# 累积值 = initializer
# for 每个元素:
# 累积值 = function(累积值, 当前元素)
# return 累积值
# ⌨️ 逐步查看reduce的过程
numbers = [1, 2, 3, 4, 5]
def add_and_show(a, b):
"""加法并显示中间过程"""
result = a + b
print(f" {a} + {b} = {result}")
return result
print("reduce过程:")
total = reduce(add_and_show, numbers)
print(f"最终结果: {total}")
# 输出:
# reduce过程:
# 1 + 2 = 3
# 3 + 3 = 6
# 6 + 4 = 10
# 10 + 5 = 15
# 最终结果: 15
2.2 initializer(初始值)的作用
# 💡 initializer可以改变reduce的行为 numbers = [1, 2, 3, 4, 5] # 没有initializer——从第一个元素开始 result1 = reduce(lambda a, b: a + b, numbers) print(result1) # 15 # 有initializer=0——从0开始 result2 = reduce(lambda a, b: a + b, numbers, 0) print(result2) # 15(结果相同) # 有initializer=10——从10开始 result3 = reduce(lambda a, b: a + b, numbers, 10) print(result3) # 25 = 10 + (1+2+3+4+5) # ⚠️ initializer很关键!空序列的情况 empty_list = [] # 没有initializer——报错! # reduce(lambda a, b: a + b, empty_list) # TypeError: reduce() of empty iterable with no initial value # 有initializer——安全返回 result4 = reduce(lambda a, b: a + b, empty_list, 0) print(result4) # 0 # 💡 始终提供initializer是个好习惯——让代码更安全
三、reduce()的经典应用
3.1 聚合计算
from functools import reduce
import operator
numbers = [1, 2, 3, 4, 5]
# 累加求和
total = reduce(operator.add, numbers)
print(f"求和: {total}") # 15
# 累乘求积
product = reduce(operator.mul, numbers)
print(f"求积: {product}") # 120(5的阶乘)
# 找最大值
maximum = reduce(lambda a, b: a if a > b else b, numbers)
print(f"最大值: {maximum}") # 5
# 找最小值
minimum = reduce(lambda a, b: a if a < b else b, numbers)
print(f"最小值: {minimum}") # 1
# 字符串拼接
words = ["Python", "是", "一门", "优雅的", "语言"]
sentence = reduce(lambda a, b: a + b, words)
print(sentence) # Python是一门优雅的语言
# 使用空格分隔的拼接
sentence2 = reduce(lambda a, b: f"{a} {b}", words)
print(sentence2) # Python 是 一门 优雅的 语言
3.2 实现阶乘和其他数学运算
from functools import reduce
import operator
# 阶乘 n! = 1 × 2 × 3 × ... × n
def factorial(n):
"""计算n的阶乘"""
if n < 0:
raise ValueError("阶乘只对非负整数定义")
if n == 0:
return 1
return reduce(operator.mul, range(1, n + 1))
for n in range(11):
print(f"{n}! = {factorial(n)}")
# 0! = 1
# 1! = 1
# 2! = 2
# ...
# 10! = 3628800
# 最大公约数(GCD)
import math
def gcd_of_list(numbers):
"""计算列表中所有数的最大公约数"""
if not numbers:
raise ValueError("列表不能为空")
return reduce(math.gcd, numbers)
print(gcd_of_list([48, 64, 96])) # 16
print(gcd_of_list([100, 75, 25])) # 25
print(gcd_of_list([17, 31])) # 1(互质)
# 最小公倍数(LCM)
def lcm_of_list(numbers):
"""计算列表中所有数的最小公倍数"""
if not numbers:
raise ValueError("列表不能为空")
return reduce(math.lcm, numbers) # Python 3.9+
print(lcm_of_list([4, 6, 8])) # 24
3.3 用reduce()实现map()和filter()
from functools import reduce
# 💡 reduce可以模拟map
def my_map(func, iterable):
"""用reduce实现map"""
return reduce(
lambda acc, item: acc + [func(item)],
iterable,
[] # 初始值:空列表
)
result = my_map(lambda x: x ** 2, [1, 2, 3, 4, 5])
print(result) # [1, 4, 9, 16, 25]
# 💡 reduce可以模拟filter
def my_filter(func, iterable):
"""用reduce实现filter"""
return reduce(
lambda acc, item: acc + [item] if func(item) else acc,
iterable,
[]
)
result = my_filter(lambda x: x % 2 == 0, range(1, 11))
print(result) # [2, 4, 6, 8, 10]
# ⚠️ 但实际开发中不要这样用——直接用map()和filter()或列表推导式
# 这只是用来帮助理解reduce的能力
四、reduce()的高级应用
4.1 管道/流水线处理
from functools import reduce
# 定义一系列数据处理函数
def remove_none(data):
"""移除None值"""
return [x for x in data if x is not None]
def convert_to_int(data):
"""转为整数"""
return [int(x) for x in data]
def filter_positive(data):
"""只保留正数"""
return [x for x in data if x > 0]
def multiply_by(data, factor):
"""乘以因子"""
return [x * factor for x in data]
# 用reduce链式应用这些处理
pipeline = [
remove_none,
convert_to_int,
filter_positive,
lambda data: multiply_by(data, 2),
]
raw_data = ["1", None, "3", "-2", "5", None, "0", "8"]
result = reduce(lambda data, step: step(data), pipeline, raw_data)
print(result) # [2, 6, 10, 16]
# 解释:data经过pipeline的每一层转换
# raw_data = ["1", None, "3", "-2", "5", None, "0", "8"]
# → remove_none: ["1", "3", "-2", "5", "0", "8"]
# → convert_to_int: [1, 3, -2, 5, 0, 8]
# → filter_positive: [1, 3, 5, 8]
# → multiply_by(×2): [2, 6, 10, 16]
4.2 深度合并字典
from functools import reduce
# 合并多个字典(后面的覆盖前面的)
dicts = [
{"host": "localhost", "port": 8080},
{"port": 9090, "debug": True}, # port覆盖前面的
{"timeout": 30, "retries": 3},
]
merged = reduce(lambda a, b: {**a, **b}, dicts)
print(merged)
# {'host': 'localhost', 'port': 9090, 'debug': True, 'timeout': 30, 'retries': 3}
# 深度合并(嵌套字典也合并)
configs = [
{"database": {"host": "localhost", "port": 5432}, "debug": False},
{"database": {"port": 5433, "name": "mydb"}, "cache": True},
{"debug": True, "timeout": 30},
]
def deep_merge(a, b):
"""深度合并两个字典"""
result = dict(a)
for key, value in b.items():
if key in result and isinstance(result[key], dict) and isinstance(value, dict):
result[key] = deep_merge(result[key], value)
else:
result[key] = value
return result
final_config = reduce(deep_merge, configs, {})
print(final_config)
# {'database': {'host': 'localhost', 'port': 5433, 'name': 'mydb'},
# 'debug': True, 'cache': True, 'timeout': 30}
五、reduce() vs 其他方式
from functools import reduce import operator # reduce vs 内置函数(能用内置就用内置) numbers = [1, 2, 3, 4, 5] # reduce求和 total1 = reduce(operator.add, numbers) # 15 # 内置sum()求和——更好 total2 = sum(numbers) # 15 # reduce求积 product1 = reduce(operator.mul, numbers) # 120 # Python 3.8+ math.prod()——更好 import math product2 = math.prod(numbers) # 120 # reduce找最值 max1 = reduce(lambda a, b: a if a > b else b, numbers) # 5 max2 = max(numbers) # 5 —— 更好 # reduce拼接字符串 words = ["a", "b", "c"] concat1 = reduce(lambda a, b: a + b, words) # "abc" concat2 = "".join(words) # "abc" —— 更好 # 💡 经验法则: # - 有内置函数 → 用内置函数 # - 简单聚合 → 用内置函数或for循环 # - 复杂聚合逻辑 → reduce() # - reduce让代码变难读 → 用for循环重写
六、总结
reduce()是函数式编程三件套中最后一个。它不像map()和filter()那么常用,但在需要"累积计算"的场景中,它比其他方式更自然。
核心要点:
reduce(func, iterable, [initial])将序列累积为单个值- 始终提供initializer——避免空序列报错
- 能用内置函数就用内置——
sum()、max()、math.prod()比reduce更清晰也更高效 - reduce模拟map/filter仅作学习用途——实际不要用
- 管道处理是reduce的亮点场景——在函数式数据流中非常有用
reduce的精髓:当你需要把一组数据"折叠"成一个结果时,想到它。
到此这篇关于从入门到高级详解Python中reduce()函数的使用的文章就介绍到这了,更多相关Python reduce()用法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
Python 使用 pip 安装 matplotlib 模块的方法
matplotlib是python中强大的画图模块,这篇文章主要介绍了Python 使用 pip 安装 matplotlib 模块(秒解版),本文给大家介绍的非常详细,需要的朋友可以参考下2023-02-02
Python socket.error: [Errno 98] Address already in use的原因和解决
这篇文章主要介绍了Python socket.error: [Errno 98] Address already in use的原因和解决方法,在Python的socket编程中可能会经常遇到这个问题,需要的朋友可以参考下2014-08-08
Python中不可变数据类型int, float, str, bool详解
这篇文章深入浅出解析Python中int、str、float、bool等不可变数据类型的核心特性,帮你理解对象标识、值比较与内存缓存机制,并对比可变类型,让你的代码更安全高效,需要的朋友可以参考下2026-07-07


最新评论