Skip to content

#261: The Counter Class

When working with data in Python, we often need to count occurrences of items in a list or a string. While we could write our own code to do this, Python comes with the collections module that provides a convenient and efficient way to handle this task: the Counter class.

Why should we use collections.Counter?

Counter is a subclass of the dictionary. As with the regular dictionary, it can store keys and values where the keys are unique. In addition to that basic functionality, the Counter class takes on the work of splitting strings into elements, counting the unique values in a list and offers us helpful methods to get the total of all values.

This allows us to focus on the problem at hand while the nitty-gritty work of counting values gets done by the Counter.

Import collections.Counter

We do not need to install anything; all we need to do is to import Counter from the collections module:

from collections import Counter

Create a Counter

We can create a Counter object in several ways:

  1. From a list:

1
2
3
4
fruits = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple']
fruit_counter = Counter(fruits)
print(fruit_counter)
# Output: Counter({'apple': 3, 'banana': 2, 'orange': 1})
2. From a string:

1
2
3
4
text = "hello world"
char_counter = Counter(text)
print(char_counter)
# Output: Counter({'l': 3, 'o': 2, 'h': 1, 'e': 1, ' ': 1, 'w': 1, 'r': 1, 'd': 1})
3. From a dictionary:

1
2
3
4
initial_counts = {'apple': 2, 'banana': 3}
fruit_counter = Counter(initial_counts)
print(fruit_counter)
# Output: Counter({'banana': 3, 'apple': 2})
4. Using keyword arguments:

1
2
3
fruit_counter = Counter(apple=4, banana=2, orange=1)
print(fruit_counter)
# Output: Counter({'apple': 4, 'banana': 2, 'orange': 1})

Access the tally of an element

We can access the tally of an element using the element as a key:

print(fruit_counter['apple'])
# Output: 4

If the element is not present, Counter returns 0 instead of raising a KeyError:

print(fruit_counter['grape'])
# Output: 0

Update the counter

We can update the counter for an element with the update method:

1
2
3
fruit_counter.update(['apple', 'banana', 'banana'])
print(fruit_counter)
# Output: Counter({'apple': 5, 'banana': 4, 'orange': 1})

We can also subtract the values with the subtract method:

1
2
3
fruit_counter.subtract(['apple', 'orange'])
print(fruit_counter)
# Output: Counter({'apple': 4, 'banana': 4, 'orange': 0})

Yet we can also modify the tally of an element directly:

1
2
3
4
5
6
7
print(fruit_counter)
# Output: Counter({'apple': 4, 'banana': 4, 'orange': 0})

fruit_counter['apple'] += 1

print(fruit_counter)
# Output: Counter({'apple': 5, 'banana': 4, 'orange': 0})

Get the most common elements

The most_common method returns a list of the n most common elements and their tallies:

print(fruit_counter.most_common(2))
# Output: [('apple', 5), ('banana', 4)]

Arithmetic and set operations

The Counter class supports addition, subtraction, intersection, and union operations and offers a convenient way to get the total over all elements:

counter1 = Counter(a=3, b=1)
counter2 = Counter(a=1, b=2)

# Addition
print(counter1 + counter2)
# Output: Counter({'a': 4, 'b': 3})

# Subtraction
print(counter1 - counter2)
# Output: Counter({'a': 2})

# Intersection
print(counter1 & counter2)
# Output: Counter({'a': 1, 'b': 1})

# Union
print(counter1 | counter2)
# Output: Counter({'a': 3, 'b': 2})

# Total
print(counter1)
# Counter({'a': 3, 'b': 1})
counter1.total()
# 4

Conclusion

collections.Counter is a powerful tool for counting elements in an iterable. It provides a simple and efficient way to count items, access the tallies, and perform various operations with Counter instances. Whether you are analysing text, managing inventory, or processing data, Counter can make your code cleaner and more efficient.