Counter 是 collections 模块中专为计数设计的 dict 子类,比手动用 dict 或 defaultdict(int) 更简洁高效,支持自动初始化、频次排序、most_common() 取前 N、update/subtract 运算等特性。

Counter 是什么,为什么不用 dict 手动计数
Counter 是 collections 模块里的一个类,本质是 dict 的子类,专为计数设计。它比手动用 {} + get() 或 defaultdict(int) 更简洁,自带排序、取前 N、与其它 Counter 运算等能力。手动计数容易漏初始化、写错键名,而 Counter 一行就能搞定。
最简用法:传入可迭代对象直接构造
给 Counter 传一个列表、字符串或元组,它会自动统计每个元素出现次数:
from collections import Counter
c = Counter(['a', 'b', 'a', 'c', 'b', 'a'])
print(c) # Counter({'a': 3, 'b': 2, 'c': 1})
- 返回的是
Counter对象,不是普通dict,但支持所有字典操作(如c['a']) - 未出现的键默认返回
0(c['d']不报KeyError),这点和defaultdict(int)一致 - 构造后内部已按频次降序排列(高频在前),但遍历时顺序不保证(Python 3.7+ dict 有序,
Counter继承此行为)
常用操作:取频次、取前 N、更新、相减
别只当它是“带计数的字典”,几个关键方法能省不少代码:
-
c.most_common(2)→ 返回前 2 个高频项组成的列表,如[('a', 3), ('b', 2)];不带参数则返回全部,按频次降序 -
c.update(['a', 'b', 'b'])→ 增量更新,'a'频次 +1,'b'+2 -
c.subtract(['a', 'a'])→ 减去频次,允许出现负值(c['a']可能变成 1) -
c.elements()→ 返回一个迭代器,展开成原始长度的列表(list(c.elements())≈ 原始输入顺序打乱版)
容易踩的坑:字符串、嵌套结构、性能边界
Counter 对字符串默认按字符计数,不是按词;对嵌套列表或字典会直接报 TypeError(不可哈希):
Counter('hello') # → Counter({'l': 2, 'h': 1, 'e': 1, 'o': 1})
Counter(['apple', 'banana', 'apple']) # ✅ 正常
Counter([['a'], ['b']]) # ❌ TypeError: unhashable type: 'list'
- 想按单词统计字符串?先
split():Counter(text.split()) - 想统计嵌套数据?得先扁平化或转成可哈希形式(如
tuple) - 超大列表(千万级)下,
Counter构造本身是 O(n),但比循环手写快;如果只要 Top-K,用most_common(k)比全排序更高效
真正要用好 Counter,得记住它不解决“怎么分词”或“怎么归一化”,只是把“已经准备好、可哈希”的元素数清楚——这一步没做对,后面再快也没用。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











