Python reduce()工作原理:结合cycle()按规则列表归约解析
reduce_by_rules 代码逻辑详解 这段代码实现的核心效果是按顺序循环套用规则列表里的二元操作,对输入列表做累计归约计算,逐部分拆解如下:
依赖组件基础作用
reduce:归约函数,遍历可迭代对象时,会持续用「上一步计算结果+当前元素」做输入,执行指定操作,直到遍历完所有元素返回最终值。cycle:无限迭代器构造器,传入可迭代对象后,会循环返回对象里的元素,遍历到末尾就自动从头开始,不会触发停止迭代的错误。
逐行运行逻辑
from functools import reduce from itertools import cycle def reduce_by_rules(lst, rules): rs = cycle(rules) return reduce(lambda x, y: next(rs)(x, y), lst)
- 入参说明:
lst:待做归约计算的元素列表rules:按顺序排列的二元函数列表,每个函数都要接收2个入参、返回1个计算结果(比如加法、乘法这类双参数操作)
rs = cycle(rules):提前把规则列表包装成无限循环的迭代器。举个例子,如果rules是[加, 乘, 减],那反复调用next(rs)就会按顺序返回加→乘→减→加→乘→减……无限循环。- 核心归约逻辑
reduce(lambda x, y: next(rs)(x, y), lst):
普通的reduce只会用固定的一个操作做累计,这里的lambda把固定操作换成了动态取规则的逻辑:每次要计算累计值x和当前元素y的结果时,先通过next(rs)取出当前轮到的规则函数,再把x、y作为参数传入这个规则函数计算,得到的结果作为新的累计值,进入下一轮遍历。关键细节:
rs迭代器是在reduce调用前初始化的,整个归约过程共用同一个迭代器,因此每次next都会推进规则的读取位置,不会反复从头取第一个规则。如果把cycle(rules)写在lambda内部,每次执行lambda都会新建一个迭代器,就会永远只应用第一个规则,逻辑完全错误。
运行示例
拿一组测试值走一遍流程就能完全看懂:
# 定义规则:依次做加法、乘法、减法 rules = [lambda a,b: a+b, lambda a,b: a*b, lambda a,b: a-b] test_lst = [2,3,4,5,6] print(reduce_by_rules(test_lst, rules)) # 输出21
逐轮计算过程:
- 第一轮:取列表前两个值2、3,取第一个规则(加法),计算
2+3=5 - 第二轮:累计值5,下一个元素4,取第二个规则(乘法),计算
5*4=20 - 第三轮:累计值20,下一个元素5,取第三个规则(减法),计算
20-5=15 - 第四轮:累计值15,下一个元素6,规则循环回到第一个(加法),计算
15+6=21 - 列表遍历结束,返回最终结果21。
设计思路
这个写法用cycle自动维护规则遍历的状态,不需要手动写计数器、判断规则索引什么时候要归零,用极少的代码就实现了“循环应用多规则归约”的效果,是非常典型的itertools工具函数巧用写法。
内容的提问来源于stack exchange,提问作者Nero_Gatto_290
相关产品推荐
相关产品推荐

