Counter 对象 一个计数器工具,为的是可以方便快速地计账。例如:
>>> # Tally occurrences of words in a list
>>> cnt = Counter()
>>> for word in ['red', 'blue', 'red', 'green', 'blue', 'blue']:
... cnt[word] += 1
>>> cnt
Counter({'blue': 3, 'red': 2, 'green': 1})
>>> # Find the ten most common words in Hamlet
>>> import re
>>> words = re.findall(r'\w+', open('hamlet.txt').read().lower())
>>> Counter(words).most_common(10)
[('the', 1143), ('and', 966), ('to', 762), ('of', 669), ('i', 631),
('you', 554), ('a', 546), ('my', 514), ('hamlet', 471), ('in', 451)]
一个 Counter 是一个 dict 的子类,用于计数可哈希对象。它是一个集合,元素像字典键(key)一样存储,它们的计数存储为值。计数可以是任何整数值,包括0和负数。 Counter 类有点像其他语言中的 bags或multisets。 它可以通过计数一个 iterable 中的元素来初始化,或用其它 mapping (包括 counter) 初始化:
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 Counter 对象的接口类似于字典,不同的是,如果查询的键不在 Counter 中,它会返回一个 0 而不是引发一个 KeyError: c = Counter(['eggs', 'ham']) c['bacon'] # count of a missing element is zero 0 设置一个计数为0不会从计数器中移去一个元素。使用 del 来删除它: c['sausage'] = 0 # counter entry with a zero count del c['sausage'] # del actually removes the entry 3.1 新版功能.
计数器对象除了字典方法以外,还提供了三个其他的方法:
elements() 返回一个迭代器,其中每个元素将重复出现计数值所指定次。 元素会按首次出现的顺序返回。 如果一个元素的计数值小于一,elements() 将会忽略它。 c = Counter(a=4, b=2, c=0, d=-2) sorted(c.elements()) ['a', 'a', 'a', 'a', 'b', 'b'] most_common([n]) 返回一个列表,其中包含 n 个最常见的元素及出现次数,按常见程度由高到低排序。 如果 n 被省略或为 None,most_common() 将返回计数器中的 所有 元素。 计数值相等的元素按首次出现的顺序排序: Counter('abracadabra').most_common(3) [('a', 5), ('b', 2), ('r', 2)] subtract([iterable-or-mapping]) 减去一个 可迭代对象 或 映射对象 (或 counter) 中的元素。类似于 dict.update() 但是是减去而非替换。输入和输出都可以是 0 或负数。 c = Counter(a=4, b=2, c=0, d=-2) d = Counter(a=1, b=2, c=3, d=4) c.subtract(d) c Counter({'a': 3, 'b': 0, 'c': -3, 'd': -6})
通常字典方法都可用于 Counter 对象,除了有两个方法工作方式与字典并不相同。
fromkeys(iterable) 这个类方法没有在 Counter 中实现。
update([iterable-or-mapping]) 加上一个 可迭代对象 或 映射对象 (或 counter) 中的元素。类似于 dict.update() 但是是加上而非替换。另外,可迭代对象 应当是一个元素序列,而不是一个 (key, value) 对的序列。
Counter 对象的常用案例
sum(c.values()) # total of all counts c.clear() # reset all counts list(c) # list unique elements set(c) # convert to a set dict(c) # convert to a regular dictionary c.items() # convert to a list of (elem, cnt) pairs Counter(dict(list_of_pairs)) # convert from a list of (elem, cnt) pairs c.most_common()[:-n-1:-1] # n least common elements +c # remove zero and negative counts 提供了几个数学操作,可以结合 Counter 对象,以生产 multisets (计数器中大于0的元素)。 加和减,结合计数器,通过加上或者减去元素的相应计数。交集和并集返回相应计数的最小或最大值。每种操作都可以接受带符号的计数,但是输出会忽略掉结果为零或者小于零的计数。 c = Counter(a=3, b=1) d = Counter(a=1, b=2) c + d # add two counters together: c[x] + d[x] Counter({'a': 4, 'b': 3}) c - d # subtract (keeping only positive counts) Counter({'a': 2}) c & d # intersection: min(c[x], d[x]) Counter({'a': 1, 'b': 1}) c | d # union: max(c[x], d[x]) Counter({'a': 3, 'b': 2}) 单目加和减(一元操作符)意思是从空计数器加或者减去。 c = Counter(a=2, b=-4) +c Counter({'a': 2}) -c Counter({'b': 4})
Counter 类是一个字典的子类,不限制键和值。值用于表示计数,但你实际上 可以 存储任何其他值。
most_common() 方法在值需要排序的时候用。
参与原地操作如 c[key] += 1 的值的类型只需要支持加和减,所以分数、小数和 decimals 都可以用,也支持负数。update() 和 subtract() 当然也一样,输入和输出都支持 0 和 负数。
多集方法是专为只会遇到正值的使用情况设计的。输入可以是 0 或负数,但只输出计数为正的值。没有类型限制,但值的类型需支持加、减和比较操作。