Python中按IntEnum枚举值统计列表对象数量的优雅方法
按IntEnum类型统计对象数量的优雅实现
直接用Python标准库collections.Counter即可实现零硬编码的统计逻辑,新增枚举值无需修改原有统计、输出代码,完全适配你当前的二进制解析场景。
优化后完整代码
from dataclasses import dataclass from enum import IntEnum, unique from random import randint from textwrap import dedent from collections import Counter @unique class ObjType(IntEnum): OT_START = 0 OBJTYPE_0 = 1 OBJTYPE_1 = 2 OBJTYPE_2 = 3 OT_END = 4 # 后续新增类型直接加在这里即可,其他代码不用动 @dataclass class ObjClass: t: ObjType attr_1: int = 0 attr_2: float = 0 # 其他属性... # 生成测试数据 objList = [ObjClass(randint(ObjType.OT_START + 1, ObjType.OT_END - 1)) for x in range(100)] # 一行完成按类型统计,无任何硬编码枚举值 type_counter = Counter(obj.t for obj in objList) # 自动遍历所有有效枚举类型输出,新增类型自动纳入输出 output_lines = ["list contains:"] # 自动过滤首尾占位枚举,只取业务类型 valid_types = [ot for ot in ObjType if ObjType.OT_START < ot < ObjType.OT_END] for ot in valid_types: output_lines.append(f" {type_counter.get(ot, 0)} {ot.name} objects") print(dedent("\n".join(output_lines)))
方案优势
- 无硬编码逻辑:新增枚举值只需要在
ObjType中添加定义,统计、输出代码完全不需要修改 - 性能与原生循环一致:Counter底层是C实现的计数逻辑,比手动写Python层的if分支效率更高
- 兼容原有业务逻辑:IntEnum作为可哈希类型可以直接作为Counter的键,取值方式
type_counter[ObjType.OBJTYPE_0]和原有属性访问逻辑几乎一致
如果确实需要保留原有通过属性访问计数的用法,可以在统计完成后动态生成计数对象,无需手动维护ObjListAttributes:
from types import SimpleNamespace listAttrs = SimpleNamespace(**{f"{ot.name}_count": type_counter.get(ot, 0) for ot in valid_types}) # 依旧支持原有写法访问:listAttrs.OBJTYPE_0_count
内容的提问来源于stack exchange,提问作者Fiebbo
相关产品推荐
相关产品推荐

