Counter 计数器,顾名思义就是用来计数的,最主要的作用就是计算“可迭代序列中”各个元素(element)的数量。
一个
Counter
是一个dict
的子类,用于计数可哈希对象。它是一个集合,元素像字典键(key)一样存储,它们的计数存储为值。计数可以是任何整数值,包括0和负数。
引入方式:
from collections import Counter
一个Counter
对象可以从一个iterable
被计数或从其他的mapping
初始化:
c = Counter() # a new, empty counter
c = Counter('gallahad') # a new counter from an iterable
c = Counter({'red': 4, 'blue': 2}) # a new counter from a mapping
c = Counter(cats=4, dogs=8) # a new counter from keyword args
c = Counter(['a','b','a','c']) # a new counter from a list
从python 3.7开始,Counter
也继承了记住插入顺序的功能,进行数学运算时同样会保持该顺序。
Counter
作为dict
的子类,具有和dict
一致的取值和修改值方式,但也有些细节上不同。
取值方式:
c = Counter(['eggs', 'ham'])
print(c['eggs'])
# 1
特别需要注意的是,若key
不在counter
对象中,会返回一个0
,而不是抛出异常。
c = Counter(['eggs', 'ham'])
print(c['bacon']) # count of a missing element is zero
# 0
但是,若主动将某个计数器设置为0
,也不会从counter
中将它删除。
c = Counter(['eggs', 'ham'])
c['eggs'] = 0 # counter entry with a zero count
print(dict(c))
# {'eggs': 0, 'ham': 1}
除非使用del
语句才会移除该元素。
c = collections.Counter(['eggs', 'ham'])
c['eggs'] = 0 # counter entry with a zero count
print(dict(c))
del c['eggs']
print(dict(c))
# {'eggs': 0, 'ham': 1}
# {'ham': 1}
赋予一个未在counter
中的key
一个值(即使是0
),将添加该key-value
到counter
中
c = collections.Counter(['eggs', 'ham'])
c['apple'] = 0
print(dict(c))
# {'eggs': 1, 'ham': 1, 'apple': 0}
其迭代方式和dict
一致,迭代时可以将counter
当成dict
处理。
c = collections.Counter(['eggs', 'ham', 'apple', 'banana'])
for kv in c.items():
print(kv, end=" ")
# ('eggs', 1) ('ham', 1) ('apple', 1) ('banana', 1)
counter
对象除了字典的方法外,还提供了其他的方法。
elements()
返回一个迭代器,其中每个元素将重复出现计数值所指定次。 元素会按首次出现的顺序返回。 如果一个元素的计数值小于一,elements()
将会忽略它。
c = Counter(a=4, b=2, c=0, d=-2)
pritn(sorted(c.elements()))
# ['a', 'a', 'a', 'a', 'b', 'b']
most_common([n])
返回一个列表,按出现次数排序的前n
个元素。 如果 n 被省略或为 None
,most_common()
将返回计数器中的 所有 元素。 计数值相等的元素按首次出现的顺序排序:
print(Counter('abracadabra').most_common(3))
# [('a', 5), ('b', 2), ('r', 2)]
total()
计算总计数值,并返回。
c = Counter(a=10, b=5, c=0)
print(c.total())
# 15
subtract()
减运算。
a = Counter("aab")
b = Counter('bcc')
a.subtract(b)
print(a)
# Counter({'a': 2, 'b': 0, 'c': -2})
减运算基于以下两步:1. 迭代b
中的key
,从a
中取a[key]
。2. a[key] = a[key] - b[key]
。因此,上面例子中会出现c:-2
的结果(c这个key在a
中没出现过,取值a['c']
为0
)。
注意:减运算会直接修改a
中的计数器,且没有返回值。
counter
也是一个集合,可以进行集合运算。
a = Counter("aab")
b = Counter('bcc')
print(a + b) # 并
print(a - b) # 差
print(a & b) # 与(交)
print(a | b) # 或
# Counter({'a': 2, 'b': 2, 'c': 2})
# Counter({'a': 2})
# Counter({'b': 1})
# Counter({'a': 2, 'c': 2, 'b': 1})
注意这里的差运算,是和数学概念上的集合差运算一致的,即:
A − B = { x ∣ x ∈ A 且 x ∉ B } A - B = \{x|x\in A\ 且\ x\notin B\} A−B={x∣x∈A 且 x∈/B}