每日一包 - collections.Counter

120 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第8天,点击查看活动详情

介绍

collections模块官方给出的定义是该模块实现了特定目标的容器,用来提供Python标准容器tuple list dict set的替代选择。

collections模块在Python的内置类型的基础之上提供了额外的更高性能的数据类型, 比如Python中的dict 是无序的,但是collections模块中提供的OrderedDict 构建的字典就是有序的,灵活的使用collections中的扩展类对我们提高代码开发效率非常有用。

本文首先介绍Counter的使用。

使用

查看模块子类

可以通过__all__查看该模块下的子类,共有9个:

import collections
​
​
collections.__all__
 
['ChainMap',
 'Counter',
 'OrderedDict',
 'UserDict',
 'UserList',
 'UserString',
 'defaultdict',
 'deque',
 'namedtuple']

Counter

是一个计数器工具,是dict 的子类,用于计数可哈希对象,即被计数的对象不能是可变类型的数据,将得到的结果存储在一个类似于字典的Counter对象中。

通过代码示例可以帮助我们理解,Counter直接将列表中的每个元素作为key,元素的个数作为value,比我们手动的处理要更加的简单,代码也更加清楚明了。

from collections import Counter
​
​
l = [1, 2, 3, 1, 2, 3, 4, 2, 3]
counter_obj = Counter(l)
print(counter_obj)  # Counter({2: 3, 3: 3, 1: 2, 4: 1})# 不借助collections,手动实现
d = {}
for i in l:
    if i not in d:
        d[i] = 1
    else:
        d[i] += 1
​
​

可迭代的对象都可以被Counter计数,但是需要注意的是可迭代对象中的每个元素必须是不可变(hashable)的。

from collections import Counter
​
​
# 字符串计数
print(Counter("hello world"))  # Counter({'l': 3, 'o': 2, 'h': 1, 'e': 1, ' ': 1, 'w': 1, 'r': 1, 'd': 1})
# 字典计数
print(Counter({"a": 2, "b": 4}))  # Counter({'b': 4, 'a': 2})
# 这个...自行体会
print(Counter(a=3, b=5))  # Counter({'b': 5, 'a': 3})
​

由于Counter属于dict的子类,因此dict的方法Counter都是可以使用的,除了dict的方法之外,Counter也有自己的一些方法:

  • most_common(n)

返回对象中n个最常见的元素和元素的个数,按照元素数量进行排序,如果n为默认值的话,该方法会返回计数器中的所有元素和数量。

from collections import Counter
​
c = Counter('abcdeabcdabcaba')
c.most_common(3)  # [('a', 5), ('b', 4), ('c', 3)]
  • elements() - 返回一个迭代器
from collections import Counter
​
​
c = Counter('abcdeabcdabcaba')
print(c.elements())  # <itertools.chain object at 0x000001F9AFC9CFD0>
print(list(c.elements()))  # ['a', 'a', 'a', 'a', 'a', 'b', 'b', 'b', 'b', 'c', 'c', 'c', 'd', 'd', 'e']
  • substract(iterable-or-mapping)

从迭代对象或者映射对象减去元素,有点像dict.update(),但是update是替换操作,但是substract是减去操作, 即将元素数量进行减法操作,可以出现0或者是负数。

from collections import Counter
​
​
c = Counter('abcdeabcdabcaba')
d = Counter('aaaaaaabbbbbb')
c.subtract(d)
print(c)  # Counter({'c': 3, 'd': 2, 'e': 1, 'a': -2, 'b': -2})
  • 其他方法
# 计算所有元素的数量,也就是长度
sum(c.values())
​
# 某个元素的数量, a元素的数量
c["a"]
​
# 移除某个元素, b
del c["b"]

总结

在实际开发中,合理灵活的使用Counter可以让我们的代码更加高效和简洁。