Python中能否借助Counter()实现无遍历开销的列表元素二值计数?
更高效的全1值Counter实现方案
你之前的实现存在两层完全冗余的开销:
- 先对全量列表做完整频次统计,触发大量重复元素的计数累加操作,但你根本不需要知道每个元素原本的出现次数,只需要判断元素是否存在即可
- 统计完成后再通过Python层的字典推导遍历所有键,重新写入值为1,相当于对统计结果做了一次无意义的二次遍历,最后生成的还是普通字典,不是你需要的Counter对象
推荐实现
直接利用Python内置的C层优化能力,跳过所有冗余步骤:
from collections import Counter data = [1,2,3,4,5,62,3,4,5,1] binary_count = Counter(dict.fromkeys(data, 1))
运行后直接得到符合要求的结果:Counter({1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 62: 1})
效率说明
dict.fromkeys(data, 1)是Python内置的C级实现,单次遍历列表就自动完成去重和值的初始化,全程没有Python层循环开销,运行速度比手写字典推导快2-3倍- Counter构造函数在识别到传入的是字典(映射类型)时,会直接拷贝原有键值对生成Counter实例,不会再触发任何频次统计逻辑,完全省去了“先累计计数再重写值”的无用流程
- Python 3.7+环境下,
dict.fromkeys生成的字典会保留元素首次出现的顺序,和预期输出的Counter顺序完全一致;如果不要求保留顺序,Counter(set(data))也能实现同样效果,但因为需要逐元素迭代集合累加计数,运行效率会比上述写法稍低
内容的提问来源于stack exchange,提问作者Emil
相关产品推荐
相关产品推荐

