from collections import Counter
# four ways of initialization
c = Counter(['a', 'b', 'c', 'a', 'b', 'b'])
c = Counter({'a':2, 'b':3, 'c':1})
c = Counter(a=2, b=3, c=1)
c = Counter('abcabb')
print(c) # Counter({'b': 3, 'a':2, 'c': 1})
print(c['a']) # 2
c['b'] = 0
print(c) # Counter({a':2, 'c': 1, 'b': 0})
c = Counter(a=4, b=2, c=0, d=-2)
# elements
e = c.elements() # If an element’s count is less than one, elements() will ignore it
print(list(e)) # ['a', 'a', 'a', 'a', 'b', 'b']
#most_common, return a list of the n most common elements and their counts
m = Counter('abracadabra').most_common(3)
print(m) # [('a', 5), ('b', 2), ('r', 2)]
# c.most_common()[:-n-1:-1], n least common elements
n = Counter('abracadabra').most_common()[:-3:-1] # [('d', 1), ('c', 1)],
# subtract
c = Counter(a=4, b=2, c=0, d=-2)
d = Counter(a=1, b=2, c=3, d=4)
c.subtract(d)
print(c) # Counter({'a': 3, 'b': 0, 'c': -3, 'd': -6})
c = Counter('abracadabra')
print(c.keys()) # dict_keys(['a', 'b', 'r', 'c', 'd'])
print(c.values()) # dict_value([5, 2, 2, 1, 1])
#pop, remove a key and return its value, if the key does not exist, return default
t = c.pop('a')
print(t) # 5
print(c) # Counter({'b': 2, 'r': 2, 'c': 1, 'd': 1})
c.update('abcdaab') # Counter({'b': 4, 'a': 3, 'r': 2, 'c': 2, 'd': 2})
c.update({'a': 1, 'd': 5}) # Counter({'d': 7, 'b': 4, 'a': 4, 'r': 2, 'c': 2})
c = Counter('abracadabra')
print(sum(c.values())) # 11, total of all counts
print(list(c)) # ['a', 'b', 'r', 'c', 'd']
print(set(c)) # {'a', 'b', 'd', 'r', 'c'}, convert to a set
print(dict(c)) # {'a': 5, 'b': 2, 'r': 2, 'c': 1, 'd': 1}, convert to a regular dictionary
d = Counter(dict([('a', 5), ('b', 2)])) # Counter({'a': 5, 'b': 2}), convert from a list of (elem, cnt) pairs
c.clear() # reset all counts
print(c)
c = Counter({'a': 3, 'b': 0, 'c': -3, 'd': -6})
c2 = +c # Counter({'a': 3}), remove zero and negative counts
c3 = -c # Counter({'d': 6, 'c': 3}), reverse sign, only keep positive counts
c = Counter(a=3, b=1)
d = Counter(a=1, b=2)
c + d # Counter({'a': 4, 'b': 3})
c - d # Counter({'a': 2}), keeping only positive counts
c & d # Counter({'a': 1, 'b': 1}), intersection: min(c[x], d[x])
c | d # Counter({'a': 3, 'b': 2}), union: max(c[x], d[x])