最直接用Counter(列表)自动统计频次,返回Counter对象(非普通dict),支持most_common()等方法;需确保元素可哈希,空列表得空Counter;大数据推荐生成器输入,避免内存占用。

用 collections.Counter 统计列表元素频次最直接
直接调用 Counter 构造函数传入列表,它会自动构建一个类似字典的计数对象,键是元素,值是出现次数。不需要手动遍历或初始化空字典。
常见错误是误以为返回的是普通 dict —— 实际上它是 Counter 类型,支持额外方法(如 most_common()),但也能当字典用。
-
Counter对不可哈希类型(如列表、字典)会报TypeError: unhashable type,确保列表里全是字符串、数字、元组等可哈希对象 - 空列表返回空
Counter(),不是{},但布尔值为False,可用于条件判断 - 如果只关心前 N 个高频项,用
.most_common(N)比手动排序更高效
from collections import Counter
data = ['a', 'b', 'a', 'c', 'b', 'a']
cnt = Counter(data)
print(cnt) # Counter({'a': 3, 'b': 2, 'c': 1})
print(cnt['a']) # 3
print(cnt.most_common(2)) # [('a', 3), ('b', 2)]想按原始顺序保留首次出现的高频项?别依赖 Counter 默认行为
Counter 本身不记录插入顺序(Python 3.6+ 的 dict 保序,但 Counter 构造逻辑仍以计数优先,不是按遍历顺序建键)。如果需要“出现次数相同则按第一次出现位置排序”,得额外处理。
- 先用
dict.fromkeys(lst)提取去重且保序的元素列表 - 再结合
Counter查次数,手动排序:sorted(unique_keys, key=lambda x: (-cnt[x], lst.index(x))) - 注意
lst.index(x)在长列表中性能差,若频繁调用,建议预存索引映射
Counter 和手写 dict 循环比,差在哪
性能上,Counter 是 C 实现的,在大数据量时明显快于纯 Python 循环;语义上更清晰,意图直白。但它不是万能的:
立即学习“Python免费学习笔记(深入)”;
- 不支持在线更新后自动维护最大值——比如边加元素边查 top-1,仍需手动调
.most_common(1) - 对浮点数计数要小心精度问题,
0.1 + 0.2 != 0.3可能导致同一数值被算作不同键 - 如果只需要判断某个元素是否出现 ≥N 次,用
lst.count(x) >= N更轻量,不必引入Counter
从文件或生成器读数据时,别一次性转成列表再喂给 Counter
遇到大文件或流式数据,Counter 支持可迭代对象,可以直接传生成器表达式,避免内存爆掉:
from collections import Counter
# 好:逐行读,逐词计数
with open('log.txt') as f:
words = (word for line in f for word in line.split())
cnt = Counter(words)
<h1>坏:先把全部单词加载进内存</h1><h1>all_words = [word for line in f for word in line.split()]</h1><h1>cnt = Counter(all_words)另外,Counter 的 update() 方法适合分批统计,比如处理多个小文件后合并结果。
真正容易被忽略的是:Counter 的键比较基于 == 而非 is,所以自定义类实例做键时,必须正确定义 __eq__ 和 __hash__。


















