Python Counter

Learn Python Counter from the collections module with examples to count items, words, characters, add elements, update counts, use most_common(), elements(), subtract(), and Counter arithmetic.

Published

Updated

Read time 9 min read

Reviewed byDeepak Prasad

Python Counter

When you tally hashable things—log tokens, survey answers, letters in a string—you usually write d[k] = d.get(k, 0) + 1 over and over. Counter from collections is the friendlier version: think of it as a dict where each key is something you counted and each value is how many times it showed up. I keep this page close to what you actually type day to day; when you need every corner case, the official Counter documentation is the place to bookmark.

We will go from building counters from lists and strings, through reading and updating counts, word frequencies, most_common, elements, subtract, a little multiset-style arithmetic, cleanup, how this differs from a plain dict when you are counting, and a short “watch out for this” list at the end.

Tested on: Python 3.13.3; kernel 6.14.0-37-generic.


What is Counter in Python?

Each key in a Counter is one distinct item you care about; the value is how many times you saw it. Here is the shape you will use most often—counting repeats in a Python list:

python
from collections import Counter

items = ["apple", "banana", "apple", "orange", "banana", "apple"]
counter = Counter(items)

print(counter)
Output

Run that on your side and you should see something like Counter({'apple': 3, 'banana': 2, 'orange': 1})—three apples, two bananas, one orange. That pretty-printed form is just how Counter chooses to show you its contents, not a separate “counter function” returning something exotic.


Import Counter from collections

I almost always import the class directly so my code stays short:

python
from collections import Counter

c = Counter()
print(type(c).__name__)
Output

You should see the name Counter. If your codebase already uses import collections everywhere, collections.Counter(...) is still fine—pick what reads best for you and your team.


Create a Counter from a list

You can hand Counter any iterable of hashable items. Lists of strings are the usual teaching example; tuples work the same way because Counter simply walks whatever sequence you give it.

python
from collections import Counter

items = ["b", "a", "s", "h", "b", "a", "a", "a"]
print(Counter(items))
Output

You should get per-letter counts. When the repr shows higher counts first, treat that as a display convenience from Counter, not something you should bake logic on top of—when you care about order, reach for most_common or sort explicitly yourself.


Create a Counter from a string

A string is iterable character by character, so Counter counts each letter (spaces too, if they appear in your string).

python
from collections import Counter

print(Counter("banana"))
Output

You should see how many a, b, and n characters appear in "banana".


Create a Counter from a dictionary

If you already have a mapping of keys to integer counts, you can seed a Counter from it—handy when you are merging tallies from somewhere else. Values should be integers (for ordinary counting they are usually zero or positive).

python
from collections import Counter

print(Counter({"b": 3, "a": 1, "z": 10}))
Output

You should see something like Counter({'z': 10, 'b': 3, 'a': 1}) (again, the repr likes to show larger counts first so you can skim it).

You can also write Counter(b=3, c=5) when your keys are valid identifiers—no intermediate dict required.


Access counts from a Counter

For you it feels like a dict: loop keys, index counts, or use .items() when you want (key, count) pairs together.

python
from collections import Counter

my_counter = Counter("bashir")

for item in my_counter:
    print(item, my_counter[item])

for key, count in my_counter.items():
    print(key, count)
Output

Each loop prints one line per character with its count. Here is the bit that saves you typing: a missing key does not explode with KeyError—you get 0, which is exactly what you want while you are counting.

python
from collections import Counter

my_counter = Counter("bashir")
print(my_counter["z"])
Output

That prints 0. If you want the broader story of how dicts behave outside counting, the Python dictionary tutorial is a good next read.


Add or update elements in a Counter

You bump counts the way you would with a mapping (counter[key] += n), and when you have a whole batch of new observations you call update(). Think of update as “add these counts on top of what I already have,” not “throw away what I had and replace the world.”

python
from collections import Counter

counter = Counter(["apple", "banana"])
counter["apple"] += 1
counter["orange"] += 1
print(counter)

counter.update(["apple", "orange", "orange"])
print(counter)
Output

After the first block you should see two apples, one banana, one orange; after update, apples tick up again and oranges gain two more hits. When you truly need to replace a tally wholesale, assign directly—for example counter["x"] = 5—and if that pattern feels unfamiliar, the add or update dictionary values guide walks the general dict story.


Count words using Counter

Split your text into words (here I use simple whitespace splitting via str.split; for more string ideas see split a string), then count the tokens. If you normalize or clean words first, list comprehensions pair nicely with this step. When you process logs or free-text survey answers, this is usually the pipeline you end up with.

python
from collections import Counter

text = "python is easy and python is popular"
words = text.split()
counter = Counter(words)

print(counter)
Output

You should see python and is counted twice and the other words once each.


Find most common items using most_common()

most_common(n) hands you up to n pairs of (element, count) sorted from the busiest item downward. The n is “how many leaderboard rows you want,” not “only show me items whose count is at least n.” If you leave n off or pass None, you get the full ranking order described in the docs.

python
from collections import Counter

counter = Counter("banana")
print(counter.most_common(2))
Output

You should see [('a', 3), ('n', 2)]—the two highest counts in "banana", not “only letters whose count is two or more.”


Expand items using elements()

The method is spelled elements()—note the s on the end. It yields each key repeated according to its positive count, which is handy when you want to feed a multiset-style pipeline. Zero or negative counts are skipped for you here.

python
from collections import Counter

my_counter = Counter({"x": 3, "y": 2, "z": -10})

for key in my_counter.elements():
    print(key)
Output

You should see x three times and y twice, with no z lines, because non-positive counts do not expand.


Subtract counts using subtract()

When you need to back counts down, call subtract() with another iterable or mapping of deductions. It adjusts tallies in place instead of replacing your whole counter from scratch.

python
from collections import Counter

c = Counter(["a", "b", "a", "c"])
c.subtract(["a", "b", "b"])
print(c)
Output

Counts for a and b drop according to how often they appear in the argument. Keys may land on zero or dip negative; that affects elements() and some of the arithmetic helpers, so keep an eye on the sign when you are debugging.


Counter arithmetic operations

Once you are comfortable with update, subtract, and most_common, you might reach for +, -, &, and | when you want multiset-style math between two counters. The stdlib defines what each operator means for you—note that non-positive results may disappear from the printed result for some operations.

python
from collections import Counter

c1 = Counter({"x": 3, "y": 2})
c2 = Counter({"x": 1, "y": 3})
print(c1 + c2)
print(c1 - c2)
print(c1 & c2)
print(c1 | c2)
Output

You should see merged totals for +, clipped differences for -, per-key minimums for &, and per-key maximums for |, matching the official definitions.


Delete, clear, and remove zero or negative counts

You delete one key with del counter[key], wipe everything with counter.clear(), and when you want to drop zeros and negatives from a messy counter, unary + gives you a fresh counter with only positive counts—see the Counter arithmetic notes for why that works.

python
from collections import Counter

counter = Counter({"a": 2, "b": -1, "z": 0})
del counter["z"]
counter.clear()
print(counter)
Output

After clear() you should see an empty counter; del removed the z entry before the reset.


Counter vs dictionary for counting

With a plain dict you keep writing d[k] = d.get(k, 0) + 1 (or leaning on defaultdict(int)). Counter is the version where missing keys read as 0, update and subtract read like plain English, and helpers such as most_common and elements save you from reimplementing the same utilities. If you only need grouping without counts, other tools might fit better; when you care about frequencies, Counter is the idiom I reach for. When you wrap counting inside functions, passing a Counter in and out keeps your call sites small and obvious.


Common mistakes with Python Counter

Things I still catch in reviews:

  • Importing counter in lowercase—you want Counter from collections.
  • Calling Counter a “function”—for you it is a class you instantiate.
  • Expecting update() to replace values like some dict merges you have seen—it adds counts instead.
  • Reading most_common(2) as “only show counts ≥ 2”—it means “give me the top two entries by frequency.”
  • Forgetting that missing keys return 0 and then accidentally double-counting when you mix in other structures.
  • Expecting elements() to emit keys with zero or negative counts—it skips non-positive counts on purpose.
  • Assuming + or - always leaves zero or negative entries visible; the stdlib may strip non-positive entries depending on the operation.

Python Counter quick reference table

What you want What you usually write
Count an iterable Counter(items)
Count characters Counter(text)
Count words (simple split) Counter(text.split())
Bump or merge counts c[k] += n or c.update(iterable_or_mapping)
Lower counts c.subtract(iterable_or_mapping)
Top n frequencies c.most_common(n)
Expand like a multiset list(c.elements())
Strip zeros / negatives c = +c (see docs)
Sum of counts (3.10+) c.total()
Clear everything c.clear()

Summary

You can lean on Counter as a dict subclass built for counting hashable objects: build it from lists, strings, or other mappings, read missing keys as 0, grow counts with += or update(), shrink them with subtract(), inspect frequencies with most_common, and expand with elements(). Read most_common(n) as “show me the top n pairs,” not as a threshold on the counts themselves. When multiset math is what you need, the documented +, -, &, and | operators are there once the basics feel natural under your fingers.


References


Frequently Asked Questions

1. Is Counter a function in Python?

No—you import the class Counter (capital C) from collections and build instances with Counter(...); it is a dict subclass tuned for counting hashable keys, not a standalone function.

2. What does Counter.update() do for you?

It adds incoming counts onto what you already have, like pouring more tallies into the same jar; it does not wipe and replace your counter the way a plain dict.update might make you think when you are new to it.

3. What does most_common(n) return?

Up to n (element, count) pairs sorted from highest count downward, or the full ranking when you omit n or pass None, exactly as described in the official Counter docs.

4. Does Counter raise KeyError when you read a missing key?

No—that is one of the nice ergonomics for you: missing keys read as 0 so your counting loops do not need extra guards every time you look up a label you have not seen yet.
Bashir Alam

Data Analyst and Machine Learning Engineer

Computer Science graduate from the University of Central Asia, currently employed as a full-time Machine Learning Engineer at uExel. His expertise lies in OCR, text extraction, data preprocessing, and …