如何在Python列表推导式中维护累积和实现width2colspec函数
答案
完全可以通过列表推导式实现该需求,不需要在推导式内部硬维护可变累积状态——核心思路是提前生成所有分段的起始偏移量序列,再和原宽度列表配对生成元组即可。
推荐写法(可读性最佳,标准库实现)
用itertools.accumulate生成宽度的累积和,前置补0作为首个分段的起点,再通过列表推导式配对即可,和原函数逻辑100%一致:
from itertools import accumulate def width2colspec(widths): return [(start, start + w) for start, w in zip([0, *accumulate(widths)], widths)]
测试示例输入:
widths = [15,9,50,10] print(width2colspec(widths))
运行结果:
[(0, 15), (15, 24), (24, 74), (74, 84)]
逻辑说明:
accumulate(widths)会按遍历顺序生成累积求和结果,示例输入下输出序列为15, 24, 74, 84,刚好对应所有分段的终点值- 开头拼接0后得到所有分段的起点序列
[0, 15, 24, 74],和原宽度列表按位置一一对应配对,直接就能生成需要的元组
无依赖单行写法(Python3.8+,仅作练习参考)
如果不想导入标准库,还可以借助海象运算符:=在单行内维护累积状态,纯列表推导式实现:
widths = [15,9,50,10] colspecs = (cum := [0], [cum.append(cum[-1] + w) or (cum[-2], cum[-1]) for w in widths])[1]
这个写法利用了列表append()方法返回None的特性,在追加累积值的同时直接取前后两个累积值组成元组,运行结果和原函数完全一致,但可读性较差,仅适合练习场景使用,生产环境不推荐。
原有错误写法的问题
之前尝试的写法直接取widths[i]作为分段起点,没有做偏移量的累积计算,从第三个分段开始就丢失了前面的宽度总和,自然会得到错误结果。列表推导式本身不适合维护跨迭代的可变状态,提前算好依赖的前缀和序列再做推导,才是更简洁合理的实现思路。
内容的提问来源于stack exchange,提问作者Eze Dos Ka
相关产品推荐
相关产品推荐

