遍历布尔列表生成累计递增整数列表的高效实现方法
布尔列表转累计计数整数列表的高效实现
需求说明:
输入布尔列表:bool_list = [False, False, True, False, False, True, False, True, True, False]转换规则:遍历列表过程中每遇到值为
True的元素,累计计数器加1,每个位置的输出值等于当前的累计计数值,目标输出为:int_li = [0, 0, 1, 1, 1, 2, 2, 3, 4, 4]
各场景高效实现方案
Python中布尔类型是整数的子类,True等价于整数1、False等价于整数0,这个转换本质就是对列表做前缀累计求和,不需要写复杂判断,以下是不同场景下的高效写法:
无依赖最高速实现:
itertools.accumulate
这是标准库提供的C层实现,没有Python层面的循环开销,处理任意规模的纯Python列表速度都属于第一梯队,不需要额外安装第三方依赖:import itertools int_li = list(itertools.accumulate(bool_list))运行结果和目标完全一致,处理百万级元素列表的速度比普通Python循环快2~3倍。
无依赖次优实现:预分配列表+手动计数
如果不想导入itertools,可以预分配固定长度的列表,避免动态append触发的列表扩容开销,直接累加布尔值还能省掉分支判断,速度接近C实现:int_li = [0] * len(bool_list) count = 0 for idx, val in enumerate(bool_list): count += val int_li[idx] = count超大规模数据实现:NumPy向量化计算
如果处理十万级以上的超大数据集,且本身已经在用NumPy做数据处理,可以直接用NumPy的累计和方法,向量化运算的速度比itertools更快,适合批量数据处理场景:import numpy as np int_li = np.cumsum(bool_list).tolist()如果列表规模很小不推荐用这个方法,导入NumPy的固定开销会盖过速度优势。
最易读的基础实现(小列表够用)
如果列表长度在千级元素以内,用最直白的分支判断写法完全够用,逻辑没有门槛,新手也能一眼看懂:count = 0 int_li = [] for val in bool_list: if val: count += 1 int_li.append(count)这个写法的缺点是存在分支判断开销、列表动态扩容会拖慢速度,不适合处理大列表。
内容的提问来源于stack exchange,提问作者Miguel Paulino
相关产品推荐
相关产品推荐

