Technology  /  Python

๐Ÿ Python 78 guides ยท updated 2026

From first variable to OOP, generators, and real projects โ€” the language that runs everything from data pipelines to AI agents, taught the practical way.

Python Counter: Frequency Counting, Most Common Elements, and Arithmetic

Counter is a dict subclass in the collections module. It is designed for one specific job โ€” counting how often things appear โ€” and it does that job with a very clean interface. Where you would normally write a loop, initialise counts, and handle missing keys, Counter does it in one call.

Creating a Counter

from collections import Counter
# From a list
scores = Counter([85, 90, 85, 72, 90, 85, 60])
print(scores)
# Counter({85: 3, 90: 2, 72: 1, 60: 1})
# From a string (counts characters)
letters = Counter("mississippi")
print(letters)
# Counter({'s': 4, 'i': 4, 'p': 2, 'm': 1})
# From keyword arguments
inventory = Counter(apples=5, oranges=3, bananas=8)
print(inventory)
# Counter({'bananas': 8, 'apples': 5, 'oranges': 3})
# Empty counter, then update
votes = Counter()
votes.update(["Alice", "Bob", "Alice", "Alice", "Bob"])
print(votes)
# Counter({'Alice': 3, 'Bob': 2})

most_common() โ€” Top N Elements

from collections import Counter
text = "to be or not to be that is the question"
word_freq = Counter(text.split())
# Top 3 most frequent words
print(word_freq.most_common(3))
# [('to', 2), ('be', 2), ('or', 1)] โ€” ties broken by order of first appearance
# All elements sorted by frequency (most common first)
print(word_freq.most_common())

most_common(n) uses a partial sort internally โ€” O(k log n) where k is the total number of unique elements. Faster than sorting everything when you only need the top few.

Accessing Counts

from collections import Counter
c = Counter("abracadabra")
# Access like a dict โ€” missing keys return 0, not KeyError
print(c["a"]) # 5
print(c["z"]) # 0 โ€” no error
# Total count of all elements
print(sum(c.values())) # 11
# Unique elements
print(list(c.keys())) # ['a', 'b', 'r', 'c', 'd']
# Expand back to a list (each element repeated by count)
print(list(c.elements()))
# ['a', 'a', 'a', 'a', 'a', 'b', 'b', 'r', 'r', 'c', 'd']

Counter Arithmetic

Counter supports +, -, &, and | operations:

from collections import Counter
inventory_a = Counter(apples=5, oranges=3, bananas=2)
inventory_b = Counter(apples=2, oranges=4, grapes=1)
# Addition โ€” combine counts
print(inventory_a + inventory_b)
# Counter({'oranges': 7, 'apples': 7, 'bananas': 2, 'grapes': 1})
# Subtraction โ€” remove counts (drops zero/negative)
print(inventory_a - inventory_b)
# Counter({'apples': 3, 'bananas': 2}) โ€” oranges would be -1, dropped
# Intersection โ€” minimum of each count
print(inventory_a & inventory_b)
# Counter({'oranges': 3, 'apples': 2}) โ€” keys in both, smallest count wins
# Union โ€” maximum of each count
print(inventory_a | inventory_b)
# Counter({'oranges': 4, 'apples': 5, 'bananas': 2, 'grapes': 1})

Practical Patterns

Word frequency analysis:

from collections import Counter
import re
def word_frequency(text):
"""Count word frequency, case-insensitive, ignoring punctuation."""
words = re.findall(r'\b[a-z]+\b', text.lower())
return Counter(words)
sample = "Python is great. Python is also fun. Python!"
freq = word_frequency(sample)
print(freq.most_common(3))
# [('python', 3), ('is', 2), ('great', 1)]

Check if one string is an anagram of another:

from collections import Counter
def is_anagram(s1, s2):
"""Return True if s1 and s2 are anagrams (same characters, different order)."""
return Counter(s1.lower()) == Counter(s2.lower())
print(is_anagram("listen", "silent")) # True
print(is_anagram("hello", "world")) # False

Find characters that appear more than once:

from collections import Counter
def find_duplicates(s):
return [char for char, count in Counter(s).items() if count > 1]
print(find_duplicates("programming"))
# ['r', 'g', 'm']

Counter vs dict.get() vs defaultdict

All three can count, but Counter is the most expressive:

words = ["cat", "dog", "cat", "bird", "dog", "cat"]
# dict.get approach
counts = {}
for w in words:
counts[w] = counts.get(w, 0) + 1
# defaultdict approach
from collections import defaultdict
counts2 = defaultdict(int)
for w in words:
counts2[w] += 1
# Counter approach โ€” one line
from collections import Counter
counts3 = Counter(words)
# All three produce the same result, but Counter gives you most_common(),
# elements(), and arithmetic for free

Use Counter when you need counting plus any of its extra features. Use defaultdict(int) when you need a counting dict that you plan to use purely as a regular dict afterward.