Counter 实战:计数、排序与缺失值处理

举报
yd_55568944 发表于 2026/11/04 16:02:35 2026/11/04
【摘要】 介绍 Python 标准库 collections.Counter 的基本计数、增量更新、频次排序和缺失键行为,并说明零值、负值、不可哈希对象等边界条件。

Counter 实战:计数、排序与缺失值处理

collections.Counter 是专门用于统计可哈希对象出现次数的字典子类。它适合处理词频、状态分布、库存变化和日志类别汇总,比手动判断键是否存在更简洁。

1. 从可迭代对象创建计数器

下面统计任务类型出现的次数:

from collections import Counter

records = ["api", "db", "api", "worker", "db", "db"]
counts = Counter(records)

print(dict(counts))
print(counts["db"])
print(counts["cache"])

输出为:

{'api': 2, 'db': 3, 'worker': 1}
3
0

输入列表中的元素会成为键,出现次数成为值。与普通字典不同,读取不存在的键时,Counter 返回 0,不会抛出 KeyError。不过,这次读取不会自动把该键插入计数器,因此 "cache" in counts 仍然是 False。

需要注意,继承自字典的 get() 具有不同语义:

print(counts.get("cache"))
print(counts.get("cache", 0))

输出为:

None
0

因此,希望缺失项稳定得到零时,可以使用下标,或者为 get() 显式提供默认值。

2. 更新已有统计

update() 会累加而不是覆盖计数:

from collections import Counter

counts = Counter(["ok", "error", "ok"])
counts.update(["error", "timeout", "ok"])
counts.update({"error": 2})

print(dict(counts))

输出为:

{'ok': 3, 'error': 4, 'timeout': 1}

传入可迭代对象时,元素每出现一次就加一;传入映射时,则把映射中的值累加到对应键上。这适用于分批读取数据后的持续汇总。

3. 按频次排序

most_common(n) 返回出现次数最高的前 n 项,每项是 (元素, 次数) 元组:

from collections import Counter

counts = Counter(["b", "a", "b", "c", "a", "b"])
print(counts.most_common(2))
print(counts.most_common())

输出为:

[('b', 3), ('a', 2)]
[('b', 3), ('a', 2), ('c', 1)]

省略参数时会返回全部项目。若需要明确规定次数相同情况下的次序,可使用 sorted() 添加第二排序条件:

from collections import Counter

counts = Counter(["pear", "apple", "pear", "banana", "apple"])
ordered = sorted(counts.items(), key=lambda item: (-item[1], item[0]))
print(ordered)

输出为:

[('apple', 2), ('pear', 2), ('banana', 1)]

键函数先按次数降序,再按名称升序。该方式要求第二排序字段之间可以比较;如果键类型混杂,例如同时包含字符串和整数,应改用统一的可比较字段。

4. 减法、零值与负值

subtract() 会执行减法,并保留结果中的零值和负值:

from collections import Counter

stock = Counter({"pen": 5, "book": 2})
stock.subtract({"pen": 3, "book": 2, "bag": 1})

print(dict(stock))
print(dict(+stock))

输出为:

{'pen': 2, 'book': 0, 'bag': -1}
{'pen': 2}

一元加号 +stock 会生成仅保留正计数的新 Counter。如果只想删除某个键,应使用 del stock[key];把值设为零仍会保留该键,并可能影响遍历和序列化结果。

5. 边界条件与适用范围

Counter 的键必须可哈希,字符串、数字和元组通常可以作为键,列表和字典则不可以:

from collections import Counter

try:
    Counter([[1, 2], [1, 2]])
except TypeError as exc:
    print(type(exc).__name__)

输出为:

TypeError

空输入会得到空计数器。Counter 可以保存零值或负值,因此在将结果解释为“出现次数”前,应确认数据是否经过 subtract() 等操作。它适合内存中规模可控的离散数据统计;若数据量远超可用内存,通常应分批聚合,或采用能够外部存储和查询的方案。

参考资料

  • Python 标准库文档 → collections——容器数据类型 → Counter 对象
  • Python 标准库文档 → 内置函数 → sorted

说明:本文由 AI 辅助编写,示例需要读者自行验证。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。