您知道Python有成千上万的外部库,但其中最强大的工具已经包含在标准库中吗?

本系列以 '深入了解Python标准库' 为主题,逐一探讨那些常用但不深度讨论的标准库。

我们的目标是通过 以实战示例为中心,理解概念,提升代码运用能力,使您的Python使用水平更上一层楼。


collections深度使用法: 从基础到实践应用

1. 为什么从 collections 开始

collections 是对Python内置数据类型(list, dict, tuple)的补充,提供了在性能和结构上非常高效的高级集合。虽然在实际工作中经常出现,但深入讨论的情况并不多。

在本文中,我们将围绕其中最实用的五个类,告诉您‘为什么使用’、‘如何使用’、‘何时使用’。


2. Counter – 频率计数的标准,甚至更多

Count all the things!

基本概念

collections.Counter 是Python标准库 collections 模块中包含的一个非常有用的类。顾名思义,这个“计数器”是为统计数据的出现次数(频率)而优化的特殊字典。

from collections import Counter

c = Counter(['a', 'b', 'c', 'a', 'b', 'a'])
print(c)  # Counter({'a': 3, 'b': 2, 'c': 1})

若将列表、字符串、元组、字典等 可迭代对象(iterable) 传入,则会统计每个元素出现的次数。


主要功能及方法

📌 多种初始化方式

Counter 可以通过多种方式进行初始化,从而灵活地分析数据。

from collections import Counter

print(Counter(['a', 'b', 'a']))
# Counter({'a': 2, 'b': 1}) → 列表

print(Counter({'a': 2, 'b': 1}))
# Counter({'a': 2, 'b': 1}) → 字典

print(Counter(a=2, b=1))
# Counter({'a': 2, 'b': 1}) → 关键字参数

📌 元素访问

Counter 的运作方式类似于 dict,但在访问不存在的键时,会返回 0 而非 KeyError

c = Counter('hello')
print(c['l'])  # 2 (字符'l'出现2次)
print(c['x'])  # 0 ('x'未出现,但返回0而不是错误)

📌 元素的添加/修改

可以给已有元素增加值或直接修改。不存在的键也会被自动添加。

c = Counter('hello')
c['l'] += 3
print(c)
# Counter({'l': 5, 'o': 1, 'h': 1, 'e': 1})

📌 most_common(n) – 提取最常见的元素

按出现频率从高到低返回 n 个元素的元组列表。

c = Counter('banana')
print(c.most_common(2))
# [('a', 3), ('n', 2)] → 'a'出现3次,'n'出现2次

📌 elements() – 迭代器遍历元素

提供一个迭代器,以计数器的值为依据重复相关元素。

c = Counter('banana')
print(list(c.elements()))
# ['b', 'a', 'a', 'a', 'n', 'n']

但值为0或以下的元素不包含在内。


📌 支持数学运算 (Counter之间的 +, -, &, | 运算)

Counter 的一个强大之处是 支持算术/集合运算

c1 = Counter(a=3, b=1)
c2 = Counter(a=1, b=2)

print(c1 + c2)
# Counter({'a': 4, 'b': 3}) → 相同的键会合并

print(c1 - c2)
# Counter({'a': 2}) → 负数会被忽略,'b'会省略因负值而被消除

print(c1 & c2)
# Counter({'a': 1, 'b': 1}) → 交集,以最小值为标准

print(c1 | c2)
# Counter({'a': 3, 'b': 2}) → 并集,以最大值为标准

实战应用示例

📌 字符串词汇分析
text = "the quick brown fox jumps over the lazy dog"
counter = Counter(text.split())
print(counter)
📌 日志频率分析
logs = ['INFO', 'ERROR', 'INFO', 'DEBUG', 'ERROR', 'ERROR']
print(Counter(logs))  # Counter({'ERROR': 3, 'INFO': 2, 'DEBUG': 1})
📌 列表中重复元素的计数
nums = [1, 2, 2, 3, 3, 3]
print(Counter(nums))  # Counter({3: 3, 2: 2, 1: 1})

注意事项

  • Counter 继承自 dict,但 不保证排序。如果需要顺序,需使用 most_common()
  • 即使值降到0或以下,条目也不会被移除,可能需要手动过滤。
c = Counter(a=3)
c.subtract({'a': 5})
print(c)  # Counter({'a': -2})  # 值即使降到0或以下,条目依然不消失,需注意

提示: 如何在无初始化的情况下进行累加

counter = Counter()
with open("data.txt") as f:
    for line in f:
        counter.update(line.strip().split())

总结

collections.Counter 是数据分析、日志处理、文本挖掘等几乎必不可少的强大工具。对于初学者,它是一个简单的频率统计工具;而对于熟练者,则可以进化为结合运算和过滤的高级处理工具。


下一篇预告

  • defaultdict – 一个没有KeyError的世界,比dict更灵活!敬请期待下一篇!

通过 '深入理解和正确使用' 标准库,您的代码质量将会明显提升。