Counter and NamedTuple in Python

using python's derived datatypes

Introduction

In this blog we are going to explore python's specialized container datatypes NamedTuple, Counter which come from the built-in collections module. These derived datatypes provide an alternative to python's built-int datatypes list, set, tuple, and dict.

Collections module

Collections is a built-in python module that provides us with derived data types of list, set, tuple, and dict. This module consists of namedtuple, deque, ChainMap, Counter, OrderedDict, defaultdict, UserDict, UserList , UserString. You can explore all of them from the official documentation but here we are going to discuss about NamedTuple and Counter.

Counter

This is a subclass of dict used for counting the hashtable objects . Now you might think what a hashtable is? A hashtable is data structure that stores items in key value pair. Dict or Dictionary is the implementation of hashtable in python. To get started let's import Counter at first.

>>> from collections import Counter

Now let's make an instance/object of the class.

>>> c = Counter("Python is amazing")# argument as a string

While creating an instance of this class we can pass list, tuple, dict, string and keyword arguments to it.

>>> fruits = Counter(["mango" , "mango" , "apple" , "apple" , "grape"])# argument as a list
>>> vehicle = Counter({"car" : 2 , "bike" : "5" , "bus" : 10})# argument as a dictionary
>>> count = Counter(one = 1, two = 2, three = 3 , four = 4)# arguments as keyword arguments.

All of them are gonna create a Counter object which has the count of all the elements of the datatype passed to it.

>>> print("total number of a characters in the string is:",c["a"])
total number of a characters in the string is:2
>>> print("total number of mangoes in the collection is : ",fruits["mango"])
total number of mangoes in the collection is : 2
>>> print("total number of buses in the collection is : ",vehicle["bus"])
total number of buses in the collection is : 10

You get the point now it basically stores count of each element.

Methods of counter object

It supports all the methods of a dict (get, update, pop etc). But here are the special one (ones that the a dict dose not support).

elements()

This returns an iterator over elements repeating each as many times as it count. If you directly use the object it will look something like this.

>>> print(count.elements())
<itertools.chain object at 0x7fa8e6164520>

We need to convert this into a iterator or iterable. Let's just convert one of them into a list. It will ignore keys with negative count.

>>> fruits_list = list(fruits.elements())# converting the Counter object to a list
>>> fruits_list
['mango', 'mango', 'apple', 'apple', 'grape']
>>> ex = Counter(one = -1 , two = 2 ,three = 3)
>>> list(ex.elements())
['two', 'two', 'three', 'three', 'three']# one got ignore since it has negative count

most_common([n])

This method returns a list of the n most common elements and their counts from the most common to the least. If n is not passed to it it returns all the elements in the counter.

>>> print(Counter('abracadatzbra').most_common(3))# printing  out the most common 3 chars from the passed string.
[('a', 5), ('b', 2), ('r', 2)]

subtract(iterable or mapping)

This method subtracts all count of one object and returns None. Once you call the method the count values are mutated/changed.

>>> count_2 = Counter(one = 2 , two = 1 , three = 10)# creating another Counter object
>>> count.subtract(count_2)#subtracting the values from count to count_2
>>> count
Counter({'four': 4, 'two': 1, 'one': -1, 'three': -7})

total()

This methods computes the sum of all the counts.

population = Counter(man=10, women=5)
print("the total population is : "population.total())
the total population is : 15

Named Tuple

This is a quite interesting one. This returns a new tuple subclass named typename. This create a tuple-like objects that have fields accessible by indexing or attribute look up. OK let's understand what that means.

>>> from collections import namedtuple # importing namedtuple from collections
>>> Vehicle = namedtuple("Vehicle" , ["name" , "speed" , "color"])# creating a vehicle namedtuple object

Now we can use this Vehicle as a Class to create objects of it.

>>> car = Vehicle("car" , "200km/hr" , "black") # creating a car object from the namedtuple Vehicle
>>> bus = Vehicle("bus" , "120km/hr" , "red")# same as above creating a bus instance

Now let's access the values by attribute lookup at first.

>>> print("name of the vehicle is " + car.name , "and it's sped is "+car.speed)
name of the vehicle is car and it's sped is 200km/hr
>>> print("name of the vehicle is " + bus.name , "and it's sped is " + bus.speed)
name of the vehicle is bus and it's sped is 120km/hr

By indexing.

>>> print("name of the vehicle is " + car[0] , "and it's sped is "+car[1])
name of the vehicle is car and it's sped is 200km/hr
>>> print("name of the vehicle is " + bus[0] , "and it's sped is " + bus[1])
name of the vehicle is bus and it's sped is 120km/hr

Conclusion

Collection module has other data types too which are not covered in this article. You should definitely give them a try. NamedTuple and Counter can come in handy when you want to write short python code that does your job. Checkout the collections module.