In Python, Counter
is a subclass of dict
that is part of the collections
module. collections
module in Python provides specialized container data types and offer alternatives to general-purpose built-in types like lists, dictionaries, and tuples. These container data types are designed to make them more efficient and flexible to manage data.
Counter
Counter
is used to count hashable objects. It store the objects as dictionary keys and their counts as values. Counter
is like a dictionary which is used for counting items and is very useful for frequency analysis, counting occurrences of elements, words in a document, or any other type of collection.
Syntax to create Counter
object:
counter_object = collections.Counter(iterable, **kwds)
collections
is a module in Python.Counter
class is part ofcollections
module. We need to importcollections
module to useCounter
class in our program.Counter()
is theCounter
class constructoriterable
(optional) is any sequential data type object, based on which Counter object will be created.kwds
(optional) are the keyword arguments that can be used to create Counter object.- Both
iterable
andkwds
are optional parameters. If none of them is given, then empty Counter object will be created. counter_object
is the object returned
Counter
Properties
Counter
is a subclass ofdict
, it inherits all the standard dictionary methods and properties.- Elements as keys – Keys of a
Counter
are the elements of the given iterable or keyword arguments. - Counts as values – Values in the
Counter
represent the counts of each key.
Counter
Object
Create In this program, we will create Counter
object in following ways.
- Empty
Counter
object Counter
object with list as iterableCounter
object with string as iterableCounter
object with dictionary as iterableCounter
object with keyword arguments
print("create Counter object")
from collections import Counter # import Counter from collection module
# Empty Counter object
empty_counter = Counter()
print(empty_counter)
print(type(empty_counter))
# Counter object from list
courses_counter = Counter(["Python","Python","Python","PowerBI"])
print(courses_counter)
# Counter object from string
shbytes_counter = Counter("shbytes")
print(shbytes_counter)
# Counter object from dictionary
mapping_counter = Counter({"c1":"PowerBI", "c2":"Python"})
print(mapping_counter)
# Counter object from keyword arguments
args_counter = Counter(courses=5, trainings=15)
print(args_counter)
# Counter object from iterable and keyword arguments
iter_keyword_counter = Counter({"c1":"AWS", "c2":"Python"}, courses=5, trainings=15)
print(iter_keyword_counter)
In this program, first we import Counter
class from collections
module. We have created Counter object in multiple ways.
- Using
Counter()
to create empty object - Using
Counter(["Python","Python","Python","PowerBI"])
to createCounter
object from list - Using
Counter("shbytes")
to createCounter
object from string - Using
Counter({"c1":"PowerBI", "c2":"Python"})
to createCounter
object from dictionary - Using
Counter(courses=5, trainings=15)
to createCounter
object from keyword arguments - Using
Counter({"c1":"AWS", "c2":"Python"}, courses=5, trainings=15)
to createCounter
object combining iterable and keyword arguments.
Program Output
create Counter object
Counter()
<class 'collections.Counter'>
# object created from list iterable
Counter({'Python': 3, 'PowerBI': 1})
# object created from string iterable
Counter({'s': 2, 'h': 1, 'b': 1, 'y': 1, 't': 1, 'e': 1})
# object created from dictionary iterable
Counter({'c2': 'Python', 'c1': 'PowerBI'})
# object created from keyword arguments
Counter({'trainings': 15, 'courses': 5})
# object created from dictionary and keyword arguments
Counter({'c1': 'AWS', 'c2': 'Python', 'courses': 5, 'trainings': 15})
Counter
Object
Access Counter
is a subclass of dict
, it inherits all the standard dictionary methods and properties. We can access the elements from Counter
object in similar way as we accessed from dictionary objects.
Counter
element by key
Access #access Counter element by key
print("access Counter element by key")
from collections import Counter
# Create Counter object using dictionary
courses_counter = Counter(["AWS","Python","AWS","Data Science"])
print(courses_counter)
print(courses_counter["AWS"]) # Access element by key AWS
print(courses_counter["ML"]) # Access element by key ML
In this program, we have created a Counter object courses_counter
using Counter(["AWS","Python","AWS","DataScience"])
.
courses_counter["AWS"]
will access the element for keyAWS
in the object and count value forAWS
will be returned.- Using
courses_counter["ML"]
to access element for keyML
in the object.ML
is not present in theCounter
object. Count0
will be returned.
Program Output
access Counter element by key
Counter({'AWS': 2, 'Python': 1, 'Data Science': 1})
2 # For key AWS, present in Counter object
0 # For key ML, not present in Counter object
Counter
object
Iterate over We can use elements()
method to iterate over elements of Counter
object. This iterates over elements, repeating each element as many times as its count value.
# iterator over Counter object elements, repeating each as many times as its count
# elements() methods
print("iterator over Counter object elements repeating each as many times as its count")
from collections import Counter
shbytes_counter = Counter("shbytes")
print(shbytes_counter)
# Using elements() method to iterate over Counter object elements
for element in shbytes_counter.elements():
print(element)
In this program, we have created a Counter
object using string like Counter("shbytes")
. We are using shbytes_counter.elements()
method and for
loop to iterate over all elements of object.
Program Output
iterator over elements repeating each as many times as its count
Counter({'s': 2, 'h': 1, 'b': 1, 'y': 1, 't': 1, 'e': 1})
s
s
h
b
y
t
e
From the program, output, elements()
method iterates over each element and repeat it as many times as its count value. e.g. element s
count is 2
and it is repeated 2
times, element h
count is 1
and it is repeated 1
time and similarly for other elements.
most_common()
method
most_common()
method is used to find the most common elements in the Counter
. This returns list of n
most common elements and their counts.
# return list of n most common elements and their counts
# most_common([n]
print("return list of n most common elements and their counts")
from collections import Counter
most_common_counter = Counter("shbytes")
print(most_common_counter)
print(most_common_counter.most_common(2)) # Access first 2 most common elements
print(most_common_counter.most_common()[:-4:-1]) # Access elements upto index -4 from right to left
print(most_common_counter.most_common()) # Access all elements
In this program, we are accessing most common elements from Counter
object using most_common()
method.
counter.most_common(2)
will return first two elements from theCounter
object.counter.most_common()[:-4:-1]
will return the elements up to end index-4
with step-1
. It means elements will be taken from right to left up to index-4
.counter.most_common()
will return all elements fromCounter
object.
return list of n most common elements and their counts
Counter({'s': 2, 'h': 1, 'b': 1, 'y': 1, 't': 1, 'e': 1})
# First two elements
[('s', 2), ('h', 1)]
# Elements from right to left up to index -4
[('e', 1), ('t', 1), ('y', 1)]
# All elements from Counter object
[('s', 2), ('h', 1), ('b', 1), ('y', 1), ('t', 1), ('e', 1)]
Counter
Object
Update We can update existing Counter
object using update([iterable-or-mapping])
method to increase or add the element into the object and subtract([iterable-or-mapping])
method to decrease or subtract the element from the Counter object.
update()
method
update()
method updates (increase or add new element) the count for the given key element in Counter
object and if key does not exist then that key is added with positive count into the object.
# elements are counted from an iterable or added-in from another mapping (or counter)
# update([iterable-or-mapping])
print("elements are counted from an iterable or added-in from another mapping (or counter)")
from collections import Counter
# Create Counter Object
courses_counter = Counter(["Python","Python","PowerBI"])
print(courses_counter)
# Use update() method with list iterator
courses_counter.update(["Python","PowerBI"])
print(courses_counter)
# Use update() method with dictionary
courses_counter.update({"Python":2,"PowerBI":3})
print(courses_counter)
# Use update() method with another Counter object
courses_counter.update(Counter({"Python":2,"PowerBI":3}))
print(courses_counter)
- We first import the
Counter
class fromcollections
module - Using
Counter(["Python","Python","PowerBI"])
create aCounter
objectcourses_counter
, which will have key as element from list and value as count of that element. update(["Python","PowerBI"])
– UpdateCounter
object with list iterator. Count of the keys will be increased for the element.update({"Python":2,"PowerBI":3})
– UpdateCounter
object with dictionary. Count of the keys will be increased with key count in dictionary.update(Counter({"Python":2,"PowerBI":3}))
– UpdateCounter
with anotherCounter
object. Count of the keys will be increased with key count inCounter
object.- If element is not present in the
Counter
, then new element will be added from the given iterable or dictionary or Counter object.
elements are counted from an iterable or added-in from another mapping (or counter)
Counter({'Python': 2, 'PowerBI': 1}) # Original Counter Object
Counter({'Python': 3, 'PowerBI': 2}) # Update with list iterable
Counter({'Python': 5, 'PowerBI': 5}) # Update with dictionary object
Counter({'PowerBI': 8, 'Python': 7}) # Update with another Counter object
In this program, Counter object is updated multiple times with list, dictionary, or Counter object. Each time count value of the key increased (added new value to previous value) with the new value from the iterable.
subtract()
method
subtract()
method updates (decrease or subtract elements) the count for the given key element in Counter
object and if key does not exist then that key is added with negative count into the object.
# elements are subtracted from an iterable or from another mapping (or counter)
# subtract([iterable-or-mapping])
print("elements are subtracted from an iterable or from another mapping (or counter)")
from collections import Counter
# Create Counter Object
courses_counter = Counter(["Python","Python","PowerBI"])
print(courses_counter)
# Use subtract() method with list iterator
courses_counter.subtract(["Python","PowerBI"])
print(courses_counter)
# Use subtract() method with dictionary
courses_counter.subtract({"Python":2,"PowerBI":3})
print(courses_counter)
# Use subtract() method with another Counter object
courses_counter.subtract(Counter({"Python":2,"PowerBI":3}))
print(courses_counter)
- We first import the
Counter
class fromcollections
module - Using
Counter(["Python","Python","PowerBI"])
create aCounter
objectcourses_counter
, which will have key as element from list and value as count of that element. subtract(["Python","PowerBI"])
– Update (subtract)Counter
object with list iterator. Count of the keys will be decreased for the element.subtract({"Python":2,"PowerBI":3})
– Update (subtract)Counter
object with dictionary. Count of the keys will be decreased with key count in dictionary.subtract(Counter({"Python":2,"PowerBI":3}))
– Update (subtract)Counter
with anotherCounter
object. Count of the keys will be decreased with key count inCounter
object.- If element is not present in the
Counter
, then new element with negative count, will be added from the given iterable or dictionary or Counter object.
elements are subtracted from an iterable or from another mapping (or counter)
Counter({'Python': 2, 'PowerBI': 1}) # Original Counter Object
Counter({'Python': 1, 'PowerBI': 0}) # Update (subtract) with list iterable
Counter({'Python': -1, 'PowerBI': -3}) # Update (subtract) with dictionary object
Counter({'Python': -3, 'PowerBI': -6}) # Update (subtract) with another Counter object
In this program, Counter object is updated (subtracted) multiple times with list, dictionary, or Counter object. Each time count value of the key decreased (subtract new value from previous value) with the new value from the iterable.
Counter
Common Patterns
There are some common patterns which can be applicable with Counter
object.
#counter common patterns
print("counter common patterns")
from collections import Counter
char_counter = Counter("shbytes") # Create original Counter from string
print(char_counter)
print(sum(char_counter.values())) # Get total sum of Counter values
print(list(char_counter)) # Get Counter keys as list
print(set(char_counter)) # Get Counter keys as set
print(dict(char_counter)) # Get Counter elements as dictionary (key, value) item
print(char_counter.items()) # Get Counter elements as list of (key, value) items
print(Counter(dict(char_counter.items()))) # Create Counter from (key, value) items list
Program Output
counter common patterns
Counter({'s': 2, 'h': 1, 'b': 1, 'y': 1, 't': 1, 'e': 1})
7
['s', 'h', 'b', 'y', 't', 'e']
{'b', 'e', 'h', 't', 'y', 's'}
{'s': 2, 'h': 1, 'b': 1, 'y': 1, 't': 1, 'e': 1}
dict_items([('s', 2), ('h', 1), ('b', 1), ('y', 1), ('t', 1), ('e', 1)])
Counter({'s': 2, 'h': 1, 'b': 1, 'y': 1, 't': 1, 'e': 1})
Counter
remove zero or negative counts
Use +counter_object
to remove zero or negative count elements from the Counter
.
# +counter - remove zero and negative counts
print("+counter - remove zero and negative counts")
char1_counter = Counter(a=2,b=2,c=2)
char2_counter = Counter(c=2,d=1,e=1)
char1_counter.subtract(char2_counter) # subtract Counter2 from Counter1
print(char1_counter)
print(+char1_counter) # remove zero or negative count elements
char1_counter.clear() # remove all elements
print(char1_counter)
Program Output
+counter - remove zero and negative counts
Counter({'a': 2, 'b': 2, 'c': 0, 'd': -1, 'e': -1})
Counter({'a': 2, 'b': 2})
Counter()
Counter
Object
Arithmetic Operations – We can perform multiple arithmetic operations on Counter
object. Some examples of arithmetic operations are:
- Add –
counter1[x] + counter2[x]
=> This results with new Counter object that will have all unique elements from both counters. Common elements count value will be added. - Subtract –
counter1[x] - counter2[x]
=> This results with new Counter object that will have elements from the first counter, with positive count elements only. Zero or negative count elements will be removed. - Intersection –
counter1 & counter2
=> This results with new Counter object. Only elements which are present in both intersecting Counters with minimum count value =>min(c1[x], c2[x])
- Union –
counter1 | counter2
=> This results with new Counter object. Elements from both the counters will be kept. For common element element with maximum count value will be taken =>max(c1[x], c2[x])
- Unary addition for adding an empty counter =>
+char1_counter
=> keep only positive count elements. - Unary subtraction for subtracting from an empty counter =>
-char1_counter
=> keep only negative count elements.
from collections import Counter
char1_counter = Counter(a=2,b=2,c=2)
char2_counter = Counter(c=1,d=1,e=1)
# add two counters together: counter1[x] + counter2[x]
print("add two counters together: counter1[x] + counter2[x]")
add_char_counter = char1_counter + char2_counter
print(add_char_counter)
# subtract (keeping only positive counts): counter1[x] - counter2[x]
print("subtract (keeping only positive counts): counter1[x] - counter2[x]")
subtract_char_counter = char1_counter - char2_counter
print(subtract_char_counter)
# intersection: min(c1[x], c2[x]) - counter1 & counter2
print("intersection: min(c1[x], c2[x]) - counter1 & counter2")
intersect_char_counter = char1_counter & char2_counter
print(intersect_char_counter)
# union: max(c1[x], c2[x]) - counter1 | counter2
print("union: max(c1[x], c2[x]) - counter1 | counter2")
union_char_counter = char1_counter | char2_counter
print(union_char_counter)
char1_counter.subtract(char2_counter)
print(char1_counter)
# unary addition for adding an empty counter
print("unary addition for adding an empty counter")
print(+char1_counter)
#unary subtraction for subtracting from an empty counter
print("unary subtraction for subtracting from an empty counter")
print(-char1_counter)
Program Output
add two counters together: counter1[x] + counter2[x]
Counter({'c': 3, 'a': 2, 'b': 2, 'd': 1, 'e': 1})
subtract (keeping only positive counts): counter1[x] - counter2[x]
Counter({'a': 2, 'b': 2, 'c': 1})
intersection: min(c1[x], c2[x]) - counter1 & counter2
Counter({'c': 1})
union: max(c1[x], c2[x]) - counter1 | counter2
Counter({'a': 2, 'b': 2, 'c': 2, 'd': 1, 'e': 1})
Counter({'a': 2, 'b': 2, 'c': 1, 'd': -1, 'e': -1})
unary addition for adding an empty counter
Counter({'a': 2, 'b': 2, 'c': 1})
unary subtraction for subtracting from an empty counter
Counter({'d': 1, 'e': 1})
Summary
In this article, we learned about Counter
collection in Python. Following topics were discussed:
- Counter
- Create Counter Object
- Access Counter Object
- Update Counter Object
- Counter Common Patterns
- Arithmetic Operations – Counter Object
Code – Github Repository
All code snippets and programs for this article and for Python tutorial, can be accessed from Github repository – Comments and Docstring in Python.
Python Topics
Interview Questions & Answers
Q: Write a program to count the words in the given text?
- In this program, we have used collections and re (Regular Expression) module. re module is used to create token for the given text.
- We have created a
Counter
for the list of words and will get the count of each word.
from collections import Counter
import re # Regular Expression module for tokenizer
text = "This test string is only for test. This test is only for test."
# Simple word tokenizer, list of words
words = re.findall(r'\w+', text.lower())
word_counts = Counter(words)
print(word_counts)
# Counter({'test': 4, 'this': 2, 'is': 2, 'only': 2, 'for': 2, 'string': 1})
Q: Find the duplicate numbers from the given list of numbers?
from collections import Counter
numbers_list = [14, 54, 68, 54, 79, 45, 68, 14]
item_counter = Counter(numbers_list)
duplicates = [number for number, count in item_counter.items() if count > 1]
print(duplicates)
# Duplicate numbers - [14, 54, 68]
Q: Check if the given pair of words is anagram or not?
Anagrams are the words, phrases, or names formed by rearranging the letters of another. e.g. cat & act are anagram words because they can be created by rearranging letters from each other.
To check for two phrases to anagram, we just to check if Counter of both are equal or not.
from collections import Counter
def check_anagrams(str_1, str_2):
return Counter(str_1.replace(" ", "").lower()) == Counter(str_2.replace(" ", "").lower())
print(check_anagrams("listen", "silent")) # True
print(check_anagrams("Hello", "World")) # False
Q: Create a histogram for the frequency of numbers given in the list of numbers?
We will use matplotlib package of Python, to plot the histogram.
from collections import Counter
import matplotlib.pyplot as plt
numbers_list = [14, 54, 68, 54, 34, 23, 79, 45, 68, 14, 54, 14, 54]
numbers_counter = Counter(numbers_list)
plt.bar(numbers_counter.keys(), numbers_counter.values())
plt.xlabel('Numbers')
plt.ylabel('Count')
plt.title('Numbers Histogram')
plt.show()