一个Counter是dict子类,用于计数可哈希的对象。这是一个无序的容器,元素被作为字典的key存储,它们的计数作为字典的value存储。Counts允许是任何证书,包括0和负数。Counter和其它语言中的bags或者multisets类似。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对象有一个字典接口除了它们在缺失的items时候返回0而不是产生一个KeyError。设置计数为0并不会从一个counter中删除该元素,使用del来彻底删除。
>>> c = Counter(['eggs', 'ham'])
>>> c['bacon'] # count of a missing element is zero
0
>>> c['sausage'] = 0 # counter entry with a zero count
>>> del c['sausage'] # del actually removes the entry
在2.7版本的python中,Counter额外支持字典中没有的三个功能
功能 | 描述 |
---|---|
elements() | 返回一个迭代器,其中的元素重复次数和它的count一样多,元素返回次序任意,如果count小于1,将会被忽略 |
most_common([n]) | 从多到少返回一个有前n多的元素的列表,如果n被忽略或者为none,返回所有元素,相同数量的元素次序任意 |
subtract([iterable-or-mapping]) | 从当前Counter中扣除元素 |
实际应用效果如下:
>>> c = Counter(a=4, b=2, c=0, d=-2)
>>> list(c.elements())
['a', 'a', 'a', 'a', 'b', 'b']
>>> Counter('abracadabra').most_common(3)
[('a', 5), ('r', 2), ('b', 2)]
>>> 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对象有效,除了两个函数对于Counter的效用有些异常
异常函数 | 描述 |
---|---|
fromkeys(iterable) | 没有为Counter对象实现该函数 |
update([iterable-or-mapping]) | 增加count而不是用新的count取代旧的count |
对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 += Counter() # remove zero and negative counts
此外还为Counter提供了一些运算符来进行Counter对象的组合。加法和减法是对对应元素count的加减,与和或返回相应元素的最小/最大的count。输出的结果中会排除掉count小等于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=3, b=1, e=1)
>>> d = Counter(a=1, b=2, f=-2)
>>> c + d # add two counters together: c[x] + d[x]
Counter({'a': 4, 'b': 3, 'e': 1})
>>> c - d # subtract (keeping only positive counts)
Counter({'a': 2, 'f': 3, 'e': 1})
>>> 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, 'e': 1})
注意,Counters原来设计是使用正整数来代表计数,然而,需要小心避免不必要地排除了需要其他类型或者负数值的用例。为了帮助这些用例,以下介绍了最小范围和类型的限制。
Counter类自身是一个字典子类,没有限制其key和value,value原为代表计数的数值,但是你能够存储任何东西在value字段 most_common方法需要value能够进行排次序。 对于in-place operations 例如c[key] += 1,value类型只需要支持加减,所以分数,浮点数和小数将能够正常工作,负数也能够被支持。这对于update和subtract方法也适用。 多重集的方法仅仅被设计于适用大于0的数,输入可以有0和负数,但是输出中只会产生大于0的数值的输出。对于数值类型没有限制,但是数值类型需要支持加法,减法和比较。 elements()方法需要整数的计数,将会忽略0和负数的计数。
# -*- coding:utf-8 -*-
'''
功能:测试使用python内置模块collections
查了一些collections的资料如下:
官方文档:http://docs.python.org/2/library/collections.html
collections模块自Python 2.4版本开始被引入,包含了dict、set、list、tuple以外的一些特殊的容器类型,分别是:
deque:双向队列。引入自2.4。
defaultdict:使用工厂函数创建字典,使不用考虑缺失的字典键。引入自2.5。
namedtuple()函数:命名元组,是一个工厂函数。引入自2.6。
OrderedDict类:排序字典,是字典的子类。引入自2.7。
Counter类:为hashable对象计数,是字典的子类。引入自2.7。
'''
from collections import Counter
def collections_test():
# Counter类
# 是一个无序容器,存储元素形式为:key-value,key代表元素,value代表元素的出现频数
string = 'we are family and we love peace.We have the Greatwall and the yellow river!'
str_dict = {'A': 2, 'B': 5, 'G': 7, 'E': 90, 'M': 6, 'N': 6, 'x': 20, 'z': 30}
cou0 = Counter() # 创建出来一个空的Counter类
print(cou0)
cou1 = Counter(string) # 以字符串形式创建Counter类
print('cou1 为:------>', cou1)
cou2 = Counter(str_dict) # 以字典形式创建Counter类
print('cou2 为:------>', cou2)
cou3 = Counter(A=1, B=2, x=23, y=34, z=45, o=-5, m=0) # 以类字典形式创建即使用键值组合直接创建
print('cou3 为:------>', cou3)
print('cou3中所有元素计数总数为:',sum(cou3.values()))
print('将cou3中的键转为列表为:',list(cou3))
print('将cou3中的键转为集合为:',set(cou3))
print('将cou3中的键转为列表为:',dict(cou3))
print('将cou3中的键值转为(elem, count)形式为:',cou3.items())
print('取出计数值最小的前4个元素:',cou2.most_common()[:-4:-1])
cou1.update('balabalabalabalabala') # 增加
print('b 的值为------>', cou1['b'])
print('a 的值为------>', cou1['a'])
cou2.subtract('AA') # 这样导致‘A’的值为0但是并不是删除了key值
cou2.subtract('MMMMMMMMMM') # 这样的话‘M’的值就是负数了
print('A 的值为------>', cou2['A'])
print('M 的值为------>', cou2['M'])
print('cou2 为:------>', cou2)
# 上面A并没有被删除,删除需要使用del方法
del cou2['A']
print('cou2 为:------>', cou2 ) # 这里就没有A的key值了
# elements()方法
# 返回元素重复次数大于等于1的元素
print(list(cou3.elements()))
# 一般的运算操作也是满足的
print('cou2 和 cou3之和为:',cou2 + cou3)
print('cou2 和 cou3并集为:',cou2 | cou3)
print('cou2 和 cou3差集为:',cou2 & cou3)
print('cou2 和 cou3之差为:',cou2 - cou3)
collections_test()
from collections import OrderedDict,defaultdict
fancy = OrderedDict([('a', 1), ('b', 2), ('c', 3)])
print(fancy['c'],type(fancy))
dict_of_lists = defaultdict(list)
dict_of_lists['a'] = 'something for a'
dict_of_lists['b'] = 'something for b'
print(dict_of_lists['a'],type(dict_of_lists['a']))