Python collections模块中的Counter

除了内置(build-in)数据结构(dict,list,set,tuple)之外,python还提供了一些额外的数据结构。

1
import collections

collections提供了5种可选的数据结构:Counter,deque,OrderDict,defaultdict,namedtuple()

collections.Counter

1
from collections import Counter

简介

Counter是dict的一个子集,它可以用来计算dict中的可哈希对象。它是一个无排序集合,它的元素作为dict的key存储,对应的计数则以其value存储,例如Counter({'a':1,'b':2,'c':4})代表有1个a,2个b,4个c。Counter接受所有的整数作为其计数(包括0和负数在内)。

构造

构造一个空的Counter

1
2
3
c = Counter()
#此时c为
Counter()

从迭代器创建Counter

1
2
3
c = Counter("asdf")
#此时c为
Counter({'a':1,'s':1,'d':1,'f':1})

由字典mapping创建

1
2
3
c = Counter({'ss':1,'dd':2})
#此时c为
Counter({'dd':2,'ss':1})

由参数的keyword创建

1
2
3
c = Counter(hh = 2,ss = 6)
#此时c为
Counter({'ss':6,'hh':2}

特性

Counter有一些很有用的特性。例如,作为一个计数器,当读取Counter中不存在的key时,不会像通常dict那样返回错误,而是会返回0(意思是Counter里有0个这种key)

例如:

1
2
3
c = Counter(['a','a','c'])
#此时c为
Counter({'a':2,'c':1})
1
2
3
4
#使用dict
t = {'a':2,'c':1}
t['b']
#此时报错
1
2
3
#使用Counter
c['b']
#输出0

将Counter中的一个key的value设置为0(即将其计数清零)并不会删除这个元素,只有使用del才能将其中的元素删除。例如:

1
2
3
4
5
6
7
8
9
c = Counter(['a','a','c'])
#此时c为
Counter({'a':2,'c':1})
c['a'] = 0
#此时c为
Counter({'c':1,'a':0})
del c['c']
#此时c为
Counter({'a':0})

elements()

返回Counter()中计数大于1的所有元素。例如:

1
2
3
4
c = Counter({'a':2,'b':1,'d':0,'e':-2})
list(c.elements())
#输出
['a','a','b']

most_common([n])

返回Counter()中计数最多的n个元素。例如:

1
2
3
4
c = Counter("asdfaas")
c.most_common(2)
#输出
[('a',3),('b',2)]

subtract()

由一个Counter()减去另一个Counter()或迭代器或mapping。得到的数字可以为0或负数。例如:

1
2
3
4
5
c = Counter("addaw")
b = "adddf"
c.subtract(b)
#此时c为
Counter({'a':1,'w':1,'d':-1,'f':-1})

除此之外,Counter()还有一些dict本身有的特性。

比如

1
2
3
4
5
Counter("asdf") == Counter("fdsa") >>>> True

Counter("wwww") + Counter("ssss") >>>> Counter({'w':4,'s':4})

list(Counter("asdf")) >>>> ['a','s','d','f']

等等。

应用

Counter()计数器可以用在很多需要统计key出现字数的情景中。

例如求同素异构词(由相同的字母不同的顺序组成的词):

1
2
3
from collections import Counter
def same(s,d):
return Counter(s) == Counter(d)

求句子中出现次数最多的字母:

1
2
3
from collections import Counter
def count(d):
return Counter(d).most_common(1)

等等