Counter for Frequency Counting
`collections.Counter` is the dict-of-counts that every other 'count occurrences' implementation tries to be. It supports increment-by-add, most-common-K, and arithmetic between counters. This snippet covers the basic frequency count, the most-common-K shortcut, and the multiset arithmetic that makes Counter the right choice for inventory math and difference reports.
1,106 views
25
from collections import Counter
words = ['the', 'quick', 'brown', 'fox', 'jumps', 'over', 'the', 'lazy', 'dog']
freq = Counter(words)
print(freq)
# Counter({'the': 2, 'quick': 1, 'brown': 1, 'fox': 1, 'jumps': 1, 'over': 1, 'lazy': 1, 'dog': 1})
print(freq['the']) # 2
print(freq['cat']) # 0 (missing key returns 0, never raises)
freq.update(['the', 'dog'])
print(freq['the']) # 3
print(freq['dog']) # 2Passing an iterable to Counter produces a dict-like object where each value is the number of times the key appeared. Counter extends dict, so all dict methods work, but missing keys return 0 instead of raising. update(iterable) increments counts (it does not overwrite, unlike a normal dict update). This is the fastest way to compute character histograms, log-line frequencies, or anagram-equality checks: two strings are anagrams iff their Counters are equal.
from collections import Counter
text = 'banana mama llama drama'
letter_freq = Counter(text.replace(' ', ''))
print(letter_freq.most_common(3))
# [('a', 8), ('m', 4), ('n', 2)]
logs = ['200', '404', '200', '500', '200', '404', '301']
top_codes = Counter(logs).most_common(2)
print(top_codes) # [('200', 3), ('404', 2)]
# Bottom-K is also supported (negative K is not, but slice the full list)
bottom = letter_freq.most_common()[-3:]
print(bottom)most_common(n) returns the n keys with the highest counts as a list of (key, count) tuples. Internally it uses heapq to find the top-K in O(n log k), which beats sorting the whole counter when n is much smaller than the alphabet. Calling most_common() with no argument returns every entry sorted by count descending, which makes [-K:] the right way to get the bottom-K. This is the operation behind 'top trending', 'most-frequent error code', and word-cloud inputs.
from collections import Counter
cart = Counter(['apple', 'apple', 'banana', 'cherry'])
in_stock = Counter(['apple', 'banana', 'banana', 'date'])
# Items the cart wants but stock cannot fulfil
shortfall = cart - in_stock
print(shortfall) # Counter({'apple': 1, 'cherry': 1})
# Items in either, taking the larger count (multiset union)
total = cart | in_stock
print(total) # Counter({'apple': 2, 'banana': 2, 'cherry': 1, 'date': 1})
# Items in both, taking the smaller count (multiset intersection)
shared = cart & in_stock
print(shared) # Counter({'apple': 1, 'banana': 1})
# Combine counts (multiset sum)
total_with_dupes = cart + in_stock
print(total_with_dupes) # Counter({'apple': 3, 'banana': 3, 'cherry': 1, 'date': 1})Counter overloads the -, +, &, and | operators to treat counters as multisets. Subtraction drops keys that go to zero or below, intersection takes the elementwise minimum, union takes the elementwise maximum, and addition sums counts. This is the right tool for inventory differences ('what cannot we fulfil?'), schedule overlaps ('which slots are double-booked?'), and any 'how do these two bags compare?' question. Operator overloading is purely syntactic sugar over manual dict arithmetic, but it is much more readable.
