前言 在 Python 开发中,「统计元素频次」是高频需求(比如日志关键词计数、列表重复元素统计、文本词频分析)。很多人会用字典循环写几十行代码,但其实 collections 模块的 Counter 类,能以极简语法实现需求,还自带排序、交集等实用功能,今天就带大家吃透这个「效率工具」
一、核心知识点:Counter 是什么?
Counter 是 Python 内置的「计数字典」,本质是 dict 的子类,专门用于统计可迭代对象(列表、字符串、文件内容等)中元素的出现次数,核心特点:
- 语法极简,一行代码完成统计;
- 自带排序、去重、数学运算等功能;
- 兼容字典的所有操作(取值、修改、遍历)。
二、实战场景:3 个核心用法(从基础到进阶)
场景 1:基础用法 —— 统计列表 / 字符串元素频次
需求:统计列表中重复元素的出现次数,或字符串中字符出现频次。
from collections import Counter
1. 统计列表元素
fruits = ["apple", "banana", "apple", "orange", "banana", "apple"]
fruit_count = Counter(fruits)
print(fruit_count) # 输出:Counter({'apple': 3, 'banana': 2, 'orange': 1})
2. 统计字符串字符(含空格、标点)
text = "hello python! python is easy"
char_count = Counter(text)
print(char_count.most_common(3)) # 取前3个高频元素:[(' ', 4), ('p', 3), ('o', 3)]
关键方法:
- Counter(iterable):接收可迭代对象(列表、字符串、生成器等),返回计数字典;
- most_common(n):按频次降序排序,返回前 n 个元素的元组列表(n 省略则返回所有)。
场景 2:进阶用法 —— 统计日志文件单词频次(实战核心)
需求:统计日志文件中每个单词的出现次数,忽略空字符串,按频次排序。
from collections import Counter
def count_log_words(file_path: str) -> Counter:
# 1. 读取文件内容,按空白字符拆分单词(自动处理多空格、换行)
with open(file_path, "r", encoding="utf-8") as f:
words = f.read().split() # split() 无参数 = 匹配任意空白字符,过滤空字符串
# 2. 一行统计单词频次
return Counter(words)
# 测试运行(日志文件 test.log 内容见下文)
if __name__ == "__main__":
result = count_log_words("test.log")
# 按频次降序输出
for word, count in result.most_common():
print(f"{word} -> {count}")
运行结果:
User -> 5
2024-05-20 -> 3
low -> 3
INFO -> 2
login -> 1
success -> 1
WARN -> 1
System -> 1
memory -> 1
logout -> 1
核心优势:
- 无需手动初始化字典、写 if-else 判断,一行 Counter(words) 搞定;
- 自带 most_common() 排序,无需额外调用 sorted()。
场景 3:高级用法 —— 数学运算与灵活筛选
Counter 支持交集、并集、差集等数学运算,还能快速筛选高频 / 低频元素,适合复杂统计场景。
from collections import Counter
# 示例数据:两个文本的词频
text1 = "apple banana apple orange"
text2 = "banana orange grape apple apple"
count1 = Counter(text1.split())
count2 = Counter(text2.split())
# 1. 交集:两个文本中都出现的单词(取最小频次)
print(count1 & count2) # 输出:Counter({'apple': 2, 'banana': 1, 'orange': 1})
# 2. 并集:两个文本中所有单词(取最大频次)
print(count1 | count2) # 输出:Counter({'apple': 3, 'banana': 1, 'orange': 1, 'grape': 1})
# 3. 差集:text1 中有但 text2 中频次更低的单词(仅保留正频次)
print(count1 - count2) # 输出:Counter()(因 count1 中 apple 频次 2 < count2 的 3)
# 4. 筛选高频元素(频次 >= 2)
high_freq = {word: count for word, count in count2.items() if count >= 2}
print(high_freq) # 输出:{'apple': 3}
三、避坑指南(新手常犯错误)
1. 空元素统计:若拆分后有空白字符串(如 split(",") 处理 ",a,b," 会得到 ["", "a", "b", ""]),需先过滤:
words = [word for word in text.split(",") if word.strip()] # 过滤空字符串
count = Counter(words)
2. 大小写敏感:默认区分大小写(如 Apple 和 apple 是两个元素),需统一大小写:
words = [word.lower() for word in text.split()] # 转为小写后统计
count = Counter(words)
3. 取单个元素频次:直接用 count[word] 取值,不存在的元素返回 0(而非 KeyError):
count = Counter(["apple", "banana"])
print(count["orange"]) # 输出:0(无报错)
四、总结
Counter 是 Python 统计频次的「最优解」,核心优势:
- 语法极简:一行代码替代传统字典循环;
- 功能强大:自带排序、数学运算、安全取值;
- 场景广泛:日志分析、文本挖掘、数据清洗、面试算法题(如「Top K 高频元素」