目录
- 什么是
Counter? - 如何创建
Counter对象? Counter的核心功能与常用操作- 访问元素
- 计数元素
- 获取最常见的元素 (
most_common()) - 元素的增删改 (
elements(),update(),subtract()) - 算术和集合操作
Counter的实际应用场景Counter的注意事项
什么是 Counter?
Counter 是 Python 标准库 collections 模块中的一个类,它是一个 字典的子类,它的主要作用是:

用于计数可哈希对象。
你可以把它想象成一个特殊的字典,它的键是你要计数的元素,值是每个元素出现的次数,与普通字典不同,Counter 的键默认值为 0,当你访问一个不存在的键时,它不会抛出 KeyError,而是返回 0。
Counter 的官方文档描述是:
Counter 是一个 dict 子类,用于计数可哈希对象,它是一个集合,其中元素存储为字典键,它们的计数存储为字典值,计数可以是任何整数值,包括零或负数。
如何创建 Counter 对象?
创建 Counter 对象主要有以下几种方式:
a) 从可迭代对象创建(最常用)
你可以直接将一个列表、元组、字符串等可迭代对象传递给 Counter,它会自动统计每个元素的出现次数。
from collections import Counter
# 从列表创建
list_data = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple']
c1 = Counter(list_data)
print(c1)
# 输出: Counter({'apple': 3, 'banana': 2, 'orange': 1})
# 从字符串创建(每个字符都会被计数)
str_data = "hello world"
c2 = Counter(str_data)
print(c2)
# 输出: Counter({'l': 3, 'o': 2, 'h': 1, 'e': 1, ' ': 1, 'w': 1, 'r': 1, 'd': 1})
# 从元组创建
tuple_data = (1, 2, 3, 2, 1, 4, 1)
c3 = Counter(tuple_data)
print(c3)
# 输出: Counter({1: 3, 2: 2, 3: 1, 4: 1})
b) 从映射(字典)创建
你可以传入一个字典,Counter 会使用字典的键和值来初始化。
from collections import Counter
# 从字典创建
dict_data = {'a': 4, 'b': 2, 'c': 1}
c4 = Counter(dict_data)
print(c4)
# 输出: Counter({'a': 4, 'b': 2, 'c': 1})
c) 使用关键字参数创建
你也可以直接通过关键字参数来创建,键是元素,值是计数。
from collections import Counter
c5 = Counter(apple=3, banana=2, orange=1)
print(c5)
# 输出: Counter({'apple': 3, 'banana': 2, 'orange': 1})
d) 创建空的 Counter
from collections import Counter c_empty = Counter() print(c_empty) # 输出: Counter()
Counter 的核心功能与常用操作
a) 访问元素
Counter 继承了字典的访问方式,但它更“宽容”。
from collections import Counter
c = Counter({'apple': 3, 'banana': 2, 'orange': 1})
# 访问存在的键,返回计数值
print(c['apple'])
# 输出: 3
# 访问不存在的键,不会报错,而是返回 0
print(c['grape'])
# 输出: 0
# 如果想检查键是否存在,可以使用 in 操作符
print('apple' in c)
# 输出: True
print('grape' in c)
# 输出: False
b) 计数元素(update() 方法)
如果你想在现有 Counter 对象的基础上增加计数,可以使用 update() 方法,它接受一个可迭代对象或另一个映射对象,并将其元素计数累加到当前 Counter 中。
from collections import Counter
c = Counter({'apple': 3, 'banana': 2})
# 使用可迭代对象更新
c.update(['apple', 'orange', 'apple'])
print(c)
# 输出: Counter({'apple': 5, 'banana': 2, 'orange': 1})
# 使用另一个 Counter 更新
c_other = Counter({'banana': 3, 'grape': 1})
c.update(c_other)
print(c)
# 输出: Counter({'apple': 5, 'banana': 5, 'orange': 1, 'grape': 1})
注意: update() 是原地操作,会直接修改 Counter 对象,而不是返回一个新的。
c) 获取最常见的元素(most_common() 方法)
这是 Counter 最强大的功能之一。most_common(n) 返回一个包含 n 个最常见的元素及其计数的列表,已按计数从高到低排序,如果省略 n,则返回所有元素。
from collections import Counter
c = Counter('abracadabra')
print(c)
# 输出: Counter({'a': 5, 'b': 2, 'r': 2, 'c': 1, 'd': 1})
# 获取最常见的 3 个元素
print(c.most_common(3))
# 输出: [('a', 5), ('b', 2), ('r', 2)]
# 获取所有元素(已排序)
print(c.most_common())
# 输出: [('a', 5), ('b', 2), ('r', 2), ('c', 1), ('d', 1)]
d) 元素的增删改
-
增加计数:
- 直接通过
c[key] += 1的方式。 - 使用
update()方法(推荐,可以批量增加)。
- 直接通过
-
减少计数:
- 直接通过
c[key] -= 1的方式。 - 使用
subtract()方法(update的反向操作,会减少计数)。
from collections import Counter c = Counter({'apple': 3, 'banana': 2}) # 直接减少 c['apple'] -= 1 print(c) # 输出: Counter({'apple': 2, 'banana': 2}) # 使用 subtract() 方法 c.subtract({'apple': 1, 'banana': 3, 'orange': 1}) print(c) # 输出: Counter({'apple': 1, 'banana': -1, 'orange': 1})注意:
subtract()允许计数变为零或负数,这是Counter的一个特性。 - 直接通过
-
删除元素:
- 使用
del c[key]可以完全删除一个键值对。 - 使用
c.pop(key)可以删除并返回该键的计数值。
from collections import Counter c = Counter({'apple': 3, 'banana': 2, 'orange': 1}) del c['orange'] print(c) # 输出: Counter({'apple': 3, 'banana': 2}) popped_value = c.pop('banana') print(f"Popped value: {popped_value}") print(c) # 输出: # Popped value: 2 # Counter({'apple': 3}) - 使用
-
获取所有元素(
elements()方法)elements()方法返回一个迭代器,其中元素按任意顺序重复出现,次数由其计数决定。计数小于或等于 0 的元素不会被包含。from collections import Counter c = Counter({'apple': 2, 'banana': 1, 'orange': 0, 'grape': -1}) print(list(c.elements())) # 输出: ['apple', 'apple', 'banana'] # 'orange' (0) 和 'grape' (-1) 被忽略了
e) 算术和集合操作
Counter 对象支持一些算术和集合操作,这些操作会丢弃小于等于 0 的计数。
-
加法 ():两个
Counter的计数相加。c1 = Counter(a=3, b=1) c2 = Counter(a=1, b=2, c=4) print(c1 + c2) # 输出: Counter({'a': 4, 'b': 3, 'c': 4}) -
减法 ():从第一个
Counter中减去第二个Counter的计数,只保留正数计数。c1 = Counter(a=3, b=1) c2 = Counter(a=1, b=2, c=4) print(c1 - c2) # 输出: Counter({'a': 2}) # b 变成了 -1, 被丢弃 -
交集 (
&):取两个Counter中每个元素计数的最小值。c1 = Counter(a=3, b=2) c2 = Counter(a=1, b=3, c=1) print(c1 & c2) # 输出: Counter({'a': 1, 'b': 2}) -
并集 ():取两个
Counter中每个元素计数的最大值。c1 = Counter(a=3, b=2) c2 = Counter(a=1, b=3, c=1) print(c1 | c2) # 输出: Counter({'a': 3, 'b': 3, 'c': 1})
Counter 的实际应用场景
Counter 在处理数据时非常高效,以下是几个常见场景:
统计词频
这是最经典的用法,比如分析一篇文章中每个单词出现的频率。
from collections import Counter
import re
text = """
Python is an amazing language. Python is versatile and easy to learn.
Many people love Python because of its simplicity.
"""
# 转换为小写,并提取所有单词
words = re.findall(r'\b\w+\b', text.lower())
# 使用 Counter 统计词频
word_counts = Counter(words)
# 打印最常见的5个词
print(word_counts.most_common(5))
# 输出可能为: [('python', 3), ('is', 2), ('an', 1), ('amazing', 1), ...] (具体取决于正则和文本)
查找列表中的重复项
快速找出一个列表中哪些元素是重复的,以及重复了多少次。
from collections import Counter
items = [1, 2, 3, 4, 2, 5, 1, 2, 6, 7, 8, 1]
item_counts = Counter(items)
# 找出所有出现超过1次的元素
duplicates = {item: count for item, count in item_counts.items() if count > 1}
print(duplicates)
# 输出: {1: 3, 2: 3}
比较两个列表的差异
比较两个列表,找出哪些元素在 list_a 中比在 list_b 中多。
from collections import Counter
list_a = [1, 2, 2, 3, 4, 4, 5]
list_b = [2, 3, 4, 4, 6]
counter_a = Counter(list_a)
counter_b = Counter(list_b)
# 使用减法,找出 list_a 中独有的元素及其数量
difference = counter_a - counter_b
print(difference)
# 输出: Counter({1: 1, 2: 1, 5: 1})
Counter 的注意事项
-
不是真正的多线程安全:
Counter的操作(如update和subtract)是原子性的,但如果你在多线程环境中对同一个Counter对象进行复杂的、连续的操作(例如先检查再更新),可能会导致竞争条件,在多线程环境下,需要使用锁来保护Counter对象。 -
元素必须是可哈希的:和字典的键一样,
Counter中的元素必须是可哈希的类型(如int,str,tuple),你不能用list或dict作为Counter的键。 -
计数可以为零或负数:虽然
elements()和集合操作会忽略零或负数的计数,但Counter对象本身可以存储这些值,这在某些特定算法(如计算差集)中是有用的。 -
most_common()的时间复杂度:most_common()方法的时间复杂度大约是 O(n log n),因为它内部使用了排序,如果你的Counter非常大,频繁调用此方法可能会影响性能。
collections.Counter 是 Python 中一个极其方便且高效的工具,它将复杂的计数任务简化为几行代码。
| 特性 | 描述 |
|---|---|
| 本质 | dict 的子类,用于计数。 |
| 创建 | 可从列表、字符串、元组、字典等创建。 |
| 访问 | 像字典一样访问,不存在的键返回 0。 |
| 核心方法 | most_common() (获取高频元素), elements() (获取所有元素), update() (增加计数), subtract() (减少计数)。 |
| 算术操作 | 支持 , , &, ,结果会自动过滤掉 <= 0 的计数。 |
| 适用场景 | 词频统计、查找重复项、数据比较、数据分析等任何需要计数的场景。 |
掌握 Counter 可以让你在处理计数相关的问题时事半功倍,是 Python 工具箱中不可或缺的一员。
