How to Count Occurrences in a Python List

Say you run a coffee shop and want to know how many lattes sold this morning. In Python, you count occurrences in a list with orders.count("Latte"), and collections.Counter counts every item at once.

The part that trips people up is messy data. “Latte”, “latte” and “Latte ” with a trailing space look the same to you, but Python counts them as three different values.

So in this article, I’ll show you five ways to count occurrences, how to clean the data first, and which method is fastest. My outputs come from Python 3.12.5 and pandas 3.0.6.

The sample list we’ll count

Here’s a morning’s worth of orders from the register, one string per drink:

orders = ["Latte", "Mocha", "latte", "Cold Brew", "Latte ",
          "Mocha", "Latte", "Espresso", "Cold Brew", "Latte"]
  • Ten orders in total
  • “Latte” appears three times exactly as written
  • “latte” (lowercase) and “Latte ” (with a trailing space) are the troublemakers
  • “Mocha” and “Cold Brew” appear twice each, “Espresso” once

So the honest answer to “how many lattes?” is five, not three. Each method below has to deal with that. If you want the distinct drinks first, see getting unique values from a list.

Method 1: Count occurrences with list.count() (Recommended for one value)

When you only care about one value, list.count() is the simplest choice. It returns how many items are equal to what you pass in.

Here’s the code, run on the ten orders:

orders = ["Latte", "Mocha", "latte", "Cold Brew", "Latte ",
          "Mocha", "Latte", "Espresso", "Cold Brew", "Latte"]

print(orders.count("Latte"))                      # exact matches only
print(orders.count("Flat White"))                 # missing value -> 0, no error

clean = [o.strip().lower() for o in orders]        # fix case and stray spaces first
print(clean.count("latte"))

Output:

3
0
5

The plain call finds 3 lattes, and after cleaning the list it finds all 5.

Command Prompt output of Python list.count returning 3 exact Latte matches, 0 for a missing drink and 5 after cleaning case and spaces
count(“Latte”) returns 3, a drink that isn’t on the list returns 0, and the cleaned list gives 5 lattes.

How does this code work?

count() checks every item with ==. “latte” fails because of the lowercase l, and “Latte ” fails because of the space, so only three items match.

Asking for “Flat White” just returns 0, so you don’t need to check whether the value exists first.

The cleaning line strips spaces and lowercases every order, which turns all five lattes into the same string. Trimming text is covered in removing newlines and spaces from a string.

So here’s the catch: count() answers one value per call. Calling it once for every distinct drink means scanning the whole list again and again.

Method 2: Count every item at once with collections.Counter (Recommended for all values)

When you want the count of every drink, Counter builds them all in a single pass. It’s a dictionary of value-to-count with a few handy extras.

Same ten orders, cleaned the same way:

orders = ["Latte", "Mocha", "latte", "Cold Brew", "Latte ",
          "Mocha", "Latte", "Espresso", "Cold Brew", "Latte"]

from collections import Counter

clean = [o.strip().lower() for o in orders]
counts = Counter(clean)

print(counts)
print(counts["latte"], counts["flat white"])      # missing key -> 0
print(counts.most_common(2))

Output:

Counter({'latte': 5, 'mocha': 2, 'cold brew': 2, 'espresso': 1})
5 0
[('latte', 5), ('mocha', 2)]

How does this code work?

Counter(clean) walks the list once and adds 1 to each drink’s count. Lattes reach 5, mochas and cold brews 2, espresso 1.

Looking up a drink that isn’t there returns 0 instead of raising KeyError, and most_common(2) gives the top two sellers.

Pro Tip: Don’t build counts by calling count() for each distinct value. On 50,000 orders the difference is dramatic. More Counter features are in the Counter function in Python.

import random
import timeit
from collections import Counter

random.seed(1)
menu = [f"item{i}" for i in range(500)]
big = [random.choice(menu) for _ in range(50_000)]   # 50,000 orders, 500 drinks

slow = lambda: {x: big.count(x) for x in set(big)}
fast = lambda: Counter(big)
print("same result:", slow() == dict(fast()))
print(f"count() per value: {min(timeit.repeat(slow, number=1, repeat=3)) * 1000:8.1f} ms")
print(f"Counter:           {min(timeit.repeat(fast, number=1, repeat=3)) * 1000:8.1f} ms")

Output:

same result: True
count() per value:    281.7 ms
Counter:                1.2 ms
Command Prompt timing Python counting 50,000 orders with list.count for each value versus collections.Counter
Both approaches produce the same counts, but calling count() once per drink takes far longer than a single Counter pass.

Method 3: Count occurrences with a dictionary loop

Sometimes you need logic that Counter doesn’t give you, like cleaning or grouping each value as you go. A plain loop with dict.get() handles that.

Here’s the same count, written out by hand on the raw orders:

orders = ["Latte", "Mocha", "latte", "Cold Brew", "Latte ",
          "Mocha", "Latte", "Espresso", "Cold Brew", "Latte"]

counts = {}
for order in orders:
    key = order.strip().lower()
    counts[key] = counts.get(key, 0) + 1

for drink, n in sorted(counts.items(), key=lambda kv: kv[1], reverse=True):
    print(f"{drink:<10} {n}")

Output:

latte      5
mocha      2
cold brew  2
espresso   1

How does this code work?

For each order, the loop cleans the text into a key. counts.get(key, 0) returns the current count, or 0 the first time a drink appears, and adds 1.

Sorting the items by count, highest first, gives a ready-made sales ranking. More on dictionary counts is in counting with a Python dictionary.

Method 4: Count list items that match a condition

Sometimes the question isn’t “how many lattes” but “how many cold drinks” or “how many orders over $5.00”. sum() with a generator counts anything you can test:

orders = ["Latte", "Mocha", "latte", "Cold Brew", "Latte ",
          "Mocha", "Latte", "Espresso", "Cold Brew", "Latte"]

clean = [o.strip().lower() for o in orders]

print("cold drinks:", sum(1 for o in clean if o.startswith("cold")))
print("not latte:  ", sum(o != "latte" for o in clean))      # True counts as 1

prices = [5.25, 5.75, 5.25, 4.95, 5.25, 5.75, 5.25, 3.50, 4.95, 5.25]
print("over $5.00: ", sum(p > 5.00 for p in prices))

print("letter 'e' across all orders:", sum(o.count("e") for o in clean))

Output:

cold drinks: 2
not latte:   5
over $5.00:  7
letter 'e' across all orders: 9
Command Prompt output of Python sum counting cold drinks, non-latte orders, orders over $5.00 and the letter e across a list
Two orders are cold drinks, five aren’t lattes, seven cost more than $5.00, and the letter e appears nine times across the orders.

How does this code work?

sum(1 for o in clean if ...) adds 1 for every order that passes the test. The shorter form, sum(o != "latte" for o in clean), works because True counts as 1 and False as 0.

The last line answers a different question: how often a character appears inside the strings, not in the list itself. For a single string, see counting characters in a string.

Method 5: Count occurrences with pandas value_counts()

If the orders already live in pandas, or there are millions of them, value_counts() does the counting and sorting in one call:

orders = ["Latte", "Mocha", "latte", "Cold Brew", "Latte ",
          "Mocha", "Latte", "Espresso", "Cold Brew", "Latte"]

import pandas as pd

s = pd.Series(orders).str.strip().str.lower()
print(s.value_counts())
print(s.value_counts(normalize=True).round(2).head(2))

Output:

latte        5
mocha        2
cold brew    2
espresso     1
Name: count, dtype: int64
latte    0.5
mocha    0.2
Name: proportion, dtype: float64
Command Prompt output of pandas value_counts counting cleaned coffee orders and showing the top two shares
value_counts lists latte 5, mocha 2, cold brew 2 and espresso 1, and normalize=True shows lattes as half of all orders.

How does this code work?

.str.strip().str.lower() cleans every order, just like the list comprehension earlier. value_counts() then counts each value and sorts from most to least common.

normalize=True turns counts into shares, so lattes show as 0.5. If you only need to spot repeats, finding duplicates in a Python list is quicker.

Picking the right way to count occurrences

MethodCountsUse it when
lst.count(x)One valueYou need a single number
Counter(lst)Every valueYou need all counts or the top sellers
Dict loop with get()Every valueYou need custom cleaning or grouping
sum(cond for x in lst)MatchesYou’re counting a condition, not a value
Series.value_counts()Every valueThe data is already in pandas

If you just need the total number of orders, not per-drink counts, len() is enough, as shown in finding the size of a list.

Things to Keep in Mind When Counting List Items

  • Counting is exact. “Latte”, “latte” and “Latte ” are different values, so clean with strip().lower() first.
  • count() on a missing value returns 0; so does a Counter lookup. Neither raises an error.
  • Don’t call count() in a loop for every distinct value; use one Counter pass instead.
  • lst.count("e") counts list items equal to “e”, not letters inside the strings. Use sum(s.count("e") for s in lst) for letters.

Counting usually leads to one of these next steps:

Frequently asked questions

How do I count occurrences of an item in a Python list?

Use my_list.count(item). It returns the number of items equal to item.