Dictionaries
Counter
Specialized dictionary for counting hashable objects
Interview: Extremely common in interviews — anagrams, top-K, frequency analysis, and character problems
Counter is a dict subclass from the collections module designed for counting hashable objects. It stores elements as keys and their counts as values, providing powerful methods for frequency analysis, multiset operations, and finding the most common elements. It's one of the most interview-friendly tools in Python.
Creating Counters
Counter can be initialized in multiple ways depending on your data source:
- From iterable:
Counter("abracadabra")orCounter([1, 2, 2, 3])— counts each element - From dict:
Counter({"a": 5, "b": 3})— uses existing counts - From keyword args:
Counter(a=5, b=3)— convenient for small counters - Empty Counter:
Counter()— then update incrementally
Key Methods
- most_common(n): Returns a list of the n most common (element, count) pairs. O(n log k) using a heap — very efficient
- elements(): Iterator that yields each element repeated by its count —
list(Counter("aab").elements())→ ['a', 'a', 'b'] - update(iterable): Adds counts (doesn't replace) —
c.update("aaa")adds 3 to count of 'a' - subtract(iterable): Subtracts counts — can produce zero or negative counts
- Missing keys: Accessing a missing key returns 0 (not KeyError) — Counter is like defaultdict(int)
Counter as a Multiset
Counter supports multiset (bag) operations: addition combines counts, subtraction keeps only positive counts, intersection takes minimum counts, and union takes maximum counts. This makes Counter ideal for problems involving inventory, resource allocation, and frequency matching.
Arithmetic and Set Operations
- Addition (+):
Counter("aab") + Counter("abc")→ Counter({'a': 3, 'b': 2, 'c': 1}) - Subtraction (-): Keeps only positive results —
Counter("aab") - Counter("abc")→ Counter({'a': 1}) - Intersection (&): Takes minimum of each —
Counter("aab") & Counter("abc")→ Counter({'a': 1, 'b': 1}) - Union (|): Takes maximum of each —
Counter("aab") | Counter("abc")→ Counter({'a': 2, 'b': 1, 'c': 1}) - Unary +/-:
+cremoves zero/negative counts;-cnegates all counts
Common Interview Problems
- Anagram check:
Counter(s1) == Counter(s2)— O(n) vs sorting's O(n log n) - Top K frequent elements:
Counter(nums).most_common(k)— the canonical solution - First unique character: Build Counter, then iterate string to find first with count == 1
- Group anagrams: Use
frozenset(Counter(word).items())as grouping key - Minimum window substring: Use Counter to track required character frequencies
Counter vs defaultdict(int)
Both return 0 for missing keys, but Counter has extra methods: most_common(), elements(), update(), subtract(), and multiset operations. Use Counter when you need frequency analysis; use defaultdict(int) when you need general-purpose counting with custom logic.
Use Cases
Finding the most frequent elements (top-K problems)
Checking anagrams and character frequency matching
Inventory management and resource counting
Word frequency analysis in text processing and NLP
Multiset operations where elements can appear multiple times
Common Mistakes
Using sorted() + manual counting when Counter().most_common() is cleaner and more efficient
Forgetting that Counter.most_common() returns (element, count) tuples, not just elements
Not knowing that subtract() can produce negative counts — use - (subtraction operator) to keep only positives
Confusing update() (adds to counts) with dict.update() (replaces values) — Counter.update adds
Using Counter when a simple set suffices — Counter adds overhead for counting you may not need