Counting Frequencies with collections.Counter
15 min · Beginner
Need help? Ask a tutor on WhatsApp (opens in a new tab)Counting frequencies of elements is one of the most common tasks in programming and coding interviews. While you could write manual dictionary loops, collections.Counter does this in clean, highly optimized O(N) code and provides rich multiset math operations.
Creating and Querying Counters
Counter is a dictionary subclass that counts hashable items. Each item is a key and its count is the value.
Pass any iterable to Counter() to count item frequencies.
from collections import Counter
words = ["apple", "banana", "apple", "cherry", "banana", "apple"]counts = Counter(words)print(counts) # Counter({'apple': 3, 'banana': 2, 'cherry': 1})Example 1 · Counting page views
from collections import Counter
views = Counter(["home", "pricing", "home", "docs", "home", "pricing"])print(views["home"], views["blog"])print("blog" in views)
views.update(["blog", "home"])print(views.most_common(2))print(views.total())3 0
False
[('home', 4), ('pricing', 2)]
8What this code does
- Reading
views["blog"]gives 0 and does not add the key. update()adds to the existing counts, unlikedict.update(), which replaces values.total()adds all counts (Python 3.10+).
Querying a missing key returns 0 instead of raising a KeyError.
Finding Top-K with most_common()
most_common(k) returns the k most frequent elements as a list of (element, count) tuples.
print(counts.most_common(2)) # [('apple', 3), ('banana', 2)]Example 2 · Most frequent word in a text
from collections import Counter
text = "python placement python developer placement python"words = text.split()counter = Counter(words)
top_word, top_freq = counter.most_common(1)[0]print(f"Most frequent: '{top_word}' ({top_freq} times)")Most frequent: 'python' (3 times)
What this code does
counter.most_common(1)returns[('python', 3)].- We unpack the tuple to display the leader.
This solves top-K frequent elements problems in O(N log K) time using an internal heap.
Multiset Arithmetic
Multiset is a collection where an item can appear more than once and the number of times matters. A Counter is Python's multiset.
Counters support mathematical operations directly!
c1 = Counter(a=3, b=1)c2 = Counter(a=1, b=2)
print("c1 + c2:", c1 + c2) # Counter({'a': 4, 'b': 3})print("c1 - c2:", c1 - c2) # Counter({'a': 2}) (negative/zero dropped)print("c1 & c2:", c1 & c2) # Counter({'a': 1, 'b': 1}) (minimums)print("c1 | c2:", c1 | c2) # Counter({'a': 3, 'b': 2}) (maximums)Example 3 · Can the warehouse ship this order?
from collections import Counter
stock = Counter(laptop=5, mouse=10, cable=4)order = Counter(laptop=3, mouse=12, cable=4)
shortage = order - stockprint(shortage)print("Can ship" if not shortage else f"Short by: {dict(shortage)}")Counter({'mouse': 2})
Short by: {'mouse': 2}What this code does
order - stockkeeps only items where the order needs more than the stock has.- An empty Counter is falsy, so
not shortagemeans nothing is missing.
Multiset math makes inventory tracking and resource allocation trivial.
Solving Anagrams in One Line
Two words are anagrams if and only if their character counters are equal.
def is_anagram(s1, s2): return Counter(s1) == Counter(s2)
print(is_anagram("silent", "listen")) # TrueExample 4 · Summarise a server log
from collections import Counter
lines = ["ERROR disk full", "INFO started", "ERROR timeout", "WARN slow", "ERROR disk full"]levels = Counter(line.split()[0] for line in lines)messages = Counter(line for line in lines if line.startswith("ERROR"))
print(levels)print(messages.most_common(1))Counter({'ERROR': 3, 'INFO': 1, 'WARN': 1})
[('ERROR disk full', 2)]What this code does
- Counter accepts any iterable, including a generator expression, so no list is built first.
- Equal counts keep the order in which items were first seen.
Runs in O(N) time and O(1) auxiliary space for fixed alphabets.
Updating Counts and Negative Values
update() adds to the counts. subtract() lowers them and keeps zero and negative results, while the - operator drops them.
from collections import Counter
stock = Counter(laptop=5, mouse=10)stock.subtract(Counter(laptop=2, mouse=12))print(stock)print(+stock)
stock["laptop"] += 1print(stock["laptop"])Example 5 · Find oversold items
from collections import Counter
stock = Counter(laptop=5, mouse=10)sold = Counter(laptop=2, mouse=12)
stock.subtract(sold)print(dict(stock))oversold = [item for item, qty in stock.items() if qty < 0]print("Oversold:", oversold){'laptop': 3, 'mouse': -2}
Oversold: ['mouse']What this code does
subtract()keeps the negative result formouse.- The
-operator would have hidden it, so usesubtract()when negatives matter.
A negative count is useful: it shows how far a stock went below zero. Unary +stock keeps only the positive counts.
Next step
Check your understanding
11 quick questions