如何使用Python的Counter来自Collections模块
在本教程中,您将学习如何使用Python的collections模块中的counter对象。
当您在Python中处理长序列时,比如Python列表或字符串,有时候您可能需要存储序列中出现的“项”以及它们出现的“次数”。
Python字典是一种适用于此类应用的内置数据结构。然而,Python的collections模块中的Counter类可以简化这个过程——通过构建一个计数器,即一个包含序列中项及其计数的字典。
在接下来的几分钟内,您将学习以下内容:
- 使用Python的计数器对象
- 创建一个Python字典来存储可迭代对象中的计数值
- 使用简化的语法使用Python的计数器重写字典
- 执行操作,如更新和减去元素,找到两个计数器对象之间的交集
- 使用
most_common()
方法获取计数器中最常见的项
让我们开始吧!
Python的collections模块和Counter类
您经常会用到一个Python dictionary来存储可迭代对象中的项及其计数。项和计数分别存储为键和值。
由于Counter类是Python的内置collections模块的一部分,您可以像这样在Python脚本中导入它:
from collections import Counter
在导入了Counter类之后,您可以像下面这样实例化一个计数器对象:
= Counter(iterable)
这里:
- iterable是任何有效的Python可迭代对象,如Python列表、字符串或元组。
- 可迭代对象中的项应该是hashable。
既然我们知道如何使用Counter从任何Python可迭代对象创建计数器对象,让我们开始编码吧。
本教程中使用的示例可以在this GitHub gist中找到。
如何从Python可迭代对象创建计数器对象
让我们创建一个Python字符串,比如'renaissance',并将其命名为word
。
>>> word = "renaissance"
我们的目标是创建一个字典,其中word
字符串中的每个字母都映射到它在字符串中出现的次数。一种方法是使用for循环,如下所示:
>>> letter_count = {}
>>> for letter in word:
... if letter not in letter_count:
... letter_count[letter] = 0
... letter_count[letter] += 1
...
>>> letter_count
{'r': 1, 'e': 2, 'n': 2, 'a': 2, 'i': 1, 's': 2, 'c': 1}
让我们解析一下上面的代码片段:
- 将
letter_count
初始化为空的Python字典。 - 循环遍历
word
字符串。 - 检查
letter
是否存在于letter_count
字典中。 - 如果
letter
不存在,则将其添加为0的值,并随后将值增加1。 - 对于
word
中每个letter
的出现,对应的值会增加1。 - 这将一直进行,直到我们循环遍历整个字符串。
我们通过使用for loop自己构建了letter_count
字典来循环遍历字符串word
。
现在让我们使用collections模块中的Counter类。我们只需要将word
字符串传递给Counter()
即可获得letter_count
,而不需要循环遍历可迭代对象。
>>> from collections import Counter
>>> letter_count = Counter(word)
>>> letter_count
Counter({'e': 2, 'n': 2, 'a': 2, 's': 2, 'r': 1, 'i': 1, 'c': 1})
计数器对象也是一个 Python dictionary。我们可以使用内置的 isinstance()
函数来验证这一点:
>>> isinstance(letter_count,dict)
True
如上所示,isinstance(letter_count, dict)
返回 True
,表示计数器对象 letter_count
是 Python dict
类的一个实例。
修改计数器对象
到目前为止,我们已经学习了如何从 Python 字符串创建计数器对象。
您还可以通过从另一个可迭代对象中更新计数器对象或从计数器对象中减去另一个可迭代对象来修改计数器对象。
使用另一个可迭代对象更新计数器
让我们初始化另一个字符串 another_word
:
>>> another_word = "effervescence"
假设我们想使用 another_word
字符串的项目更新 letter_count
计数器对象。
我们可以使用计数器对象 letter_count
上的 update()
方法。
>>> letter_count.update(another_word)
>>> letter_count
Counter({'e': 7, 'n': 3, 's': 3, 'c': 3, 'r': 2, 'a': 2, 'f': 2, 'i': 1, 'v': 1})
在输出中,我们可以看到计数器对象已经更新,也包括了来自 another_word
的字母和它们的出现次数。
从另一个可迭代对象中减去元素
现在让我们从 letter_count
对象中减去 another_word
的值。为此,我们可以使用 subtract()
方法。使用 .subtract()
从 中减去
中的项目对应的值。
让我们从 letter_count
中减去 another_word
。
>>> letter_count.subtract(another_word)
>>> letter_count
Counter({'e': 2, 'n': 2, 'a': 2, 's': 2, 'r': 1, 'i': 1, 'c': 1, 'f': 0, 'v': 0})
我们可以看到与 another_word
的字母对应的值已经被减去了,但是添加的键 ‘f' 和 ‘v' 没有被删除。它们现在映射到值 0。
注意:在这里,我们将 Python 字符串
another_word
传递给subtract()
方法调用。我们也可以传递一个 Python 计数器对象或另一个可迭代对象。
计数器对象之间的交集
有时候您可能希望找到两个 Python 计数器对象之间的交集,以确定两者之间共有哪些键。
让我们创建一个计数器对象,比如说,从字符串 ‘effervescence' 创建的 letter_count_2
计数器对象。
>>> another_word = "effervescence"
>>> letter_count_2 = Counter(another_word)
>>> letter_count_2
Counter({'e': 5, 'f': 2, 'c': 2, 'r': 1, 'v': 1, 's': 1, 'n': 1})
我们可以使用简单的 & 运算符找到 letter_count
和 letter_count_2
之间的交集。
>>> letter_count & letter_count_2
Counter({'e': 2, 'r': 1, 'n': 1, 's': 1, 'c': 1})
请注意,您可以获取两个单词之间共有的键及其出现次数。'renaissance' 和 ‘effervescence' 都包含两次 ‘e' 的出现次数,以及各自共有一次 ‘r'、'n'、's' 和 ‘c' 的出现次数。
使用 most_common 找到最常出现的项目
Python 计数器对象上的另一个常见操作是找到最常出现的项目。
要获取计数器中前k个最常见的项目,可以在计数器对象上使用most_common()
方法。在这里,我们调用letter_count
上的most_common()
来找到出现频率最高的三个字母。
>>> letter_count.most_common(3)
[('e', 2), ('n', 2), ('a', 2)]
我们可以看到字母'e','n'和'a'在单词'renaissance'中出现了两次。
如果计数器包含大量的条目并且您对处理最常见的键感兴趣,这将非常有帮助。
结论
以下是本教程中学到的内容的快速回顾:
- Python的内置collections模块中的
Counter
类可用于获取任何可迭代对象中所有项目的计数值字典。您应确保可迭代对象中的所有项目都是可哈希的。 - 您可以使用
update()
方法以counter1.update(counter2)
的语法从另一个计数器对象或任何其他可迭代对象更新一个Python计数器对象的内容。请注意,您可以在counter2
的位置使用任何可迭代对象。 - 如果您想从更新的计数器中删除一个可迭代对象的内容,您可以使用
subtract()
方法:counter1.subtract(counter2)
。 - 要找到两个计数器对象之间的公共元素,可以使用&运算符。给定两个计数器
counter1
和counter2
,counter1 & counter2
返回这两个计数器对象的交集。 - 要获取计数器中最常见的k个项目,可以使用
most_common()
方法。counter.most_common(k)
给出k个最常见的项目和相应的计数。
接下来,了解defaultdict
,这是collections模块中的另一个类。您可以使用defaultdict来处理缺少的键,而不是普通的Python字典。