探索Python集合模块中的计数器对象
在本指南中,我们将深入了解如何有效利用Python集合模块中的Counter
对象。 当您在Python中操作长序列(例如列表或字符串)时,经常需要记录序列中每个元素的出现次数。
虽然Python字典可以作为此类需求的内置数据结构,但collections
模块提供的Counter
类能够更加简化此过程。Counter
本质上是一个特殊的字典,它能够存储序列中每个元素的计数信息。
在接下来的时间里,您将学习到:
- 如何运用Python的计数器对象
- 如何创建Python字典来存储可迭代对象中元素的计数
- 如何使用Python计数器更简洁地实现字典功能
- 如何执行诸如更新和减少元素,以及查找两个计数器对象之间的交集等操作
- 如何使用
most_common()
方法获取计数器中出现频率最高的元素
让我们开始深入学习吧!
Python集合模块和计数器类
在处理可迭代对象时,你可能会经常使用Python字典来存储每个元素的计数。字典的键和值分别对应元素和它们的计数。
由于Counter
类是Python内置collections
模块的一部分,你需要先导入它:
from collections import Counter
导入Counter
类后,您可以像这样创建一个计数器对象:
<counter_object> = Counter(iterable)
这里的iterable
可以是任何Python可迭代对象,比如列表、字符串或元组,并且iterable
中的元素必须是可哈希的。
现在我们已经了解了如何通过可迭代对象创建计数器对象,让我们开始进行实际操作。本教程中使用的代码示例可以在此GitHub gist中找到。
如何使用可迭代对象创建计数器对象
首先,我们创建一个名为word
的Python字符串:’renaissance’。
>>> word = "renaissance"
我们的目标是创建一个字典,其中字符串中的每个字母都映射到其出现的次数。一种方法是使用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_count
字典中。 - 如果字母不存在,则添加该字母,初始值设为0,然后将值递增1。
- 每次在
word
中出现该字母,其对应值就会加1。 - 这个过程会持续到遍历完整个字符串为止。
我们通过for
循环遍历字符串的方式,手动创建了letter_count
字典。
现在,让我们使用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字典。我们可以使用内置的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()
方法。使用<counter-object>.subtract(<some-iterable>)
从<counter-object>
中减去与<some-iterable>
中元素对应的值。
让我们从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。
**注意:**在这里,我们将another_word
(一个Python字符串)传递给了subtract()
方法调用。我们还可以传入一个Python计数器对象或任何其他可迭代对象。
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()
方法将一个Python计数器对象的内容更新为另一个计数器对象或任何其他可迭代对象的内容,语法为:counter1.update(counter2)
。请注意,你可以使用任何可迭代对象来替代counter2
。 - 如果想从计数器中移除另一个可迭代对象中的元素,可以使用
subtract()
方法:counter1.subtract(counter2)
。 - 要查找两个计数器对象的公共元素,可以使用
&
运算符。 给定两个计数器counter1
和counter2
,counter1 & counter2
返回这两个计数器对象的交集。 - 要获得计数器中出现频率最高的k个元素,可以使用
most_common()
方法。counter.most_common(k)
返回k个最常见元素及其各自的计数。
下一步,学习如何使用defaultdict
,collections
模块中的另一个类。你可以使用默认字典而不是常规的Python字典来处理丢失的键。