• Home
  • /
  • Blog
  • /
  • 9 Useful Containers in Python Collection Module You Should Know

9 Useful Containers in Python Collection Module You Should Know

Best Creative Tools for Kids

This post is also available in: हिन्दी (Hindi) العربية (Arabic)

What are Containers or Python Collections

Containers or Python Collections are objects that are used to store different objects and provide a way to access the contained objects and iterate over them.

Python provides a number of container datatypes, both built-in types and those in the collections module in the Python Standard Library

Different data containers serve different purposes, provide different functionality, and present potentially very different computational performance for similar types of calculations. Thus, choosing the right container for the task at hand is an important step in achieving good performance. Collections in Python are the containers that are used to store collections of data, for example, list, dict, set, tuple, etc. These are built-in collections. Apart from these several other modules have been developed that provide additional data structures to store collections of data. One such module is the Python Collection Module.

Containers in Python Collection Module

Python’s collection module provides the following 9 different containers.

1. Counter

A Counter is a container that keeps track of how many times equivalent values are added. Python counter class is a part of the collections module and is a subclass of a dictionary.

You may think of counters as an unordered collection of items where items are stored as dictionary keys and their count as dictionary values.

Containers in Python
Counter

Counter items can be positive, zero, or negative integers. Though there is no restriction in its keys and values, generally the values are intended to be numbers but can store other object types also.

Counter supports three forms of initialization:

  • Its constructor can be called with a sequence of items
  • A dictionary containing keys and counts
  • Using keyword arguments mapping string names to counts

The following code demonstrates its use.

import collections
print (collections.Counter(['a', 'b', 'c', 'a', 'b', 'b']))
print (collections.Counter({'a': 2, 'b': 3, 'c':1}))
print(collections.Counter(a=2, b=3, c=1))

The output from all the three forms of initialization are the same:

Counter({'b': 3, 'a': 2, 'c': 1})
Counter({'b': 3, 'a': 2, 'c': 1})
Counter({'b': 3, 'a': 2, 'c': 1})

2. OrderedDict

The OrderedDict is a subclass of dict object in Python. The only difference between OrderedDict and Dict is that in OrderedDict, it maintains the orders of keys as inserted. In the dict, the ordering may or may not happen.

In this example, we can see that the ordering of the Dict may vary. But for the OrderedDict. It will be fixed.

import collections
#Create normal dict
my_dict = {}
my_dict['AA'] = 11
my_dict['CC'] = 33
my_dict['BB'] = 22
my_dict['DD'] = 44
for item in my_dict.items():
   print(item)
print()
#Create ordered dict
my_ord_dict = collections.OrderedDict()
my_dict['AA'] = 11
my_dict['CC'] = 33
my_dict['BB'] = 22
my_dict['DD'] = 44
for item in my_ord_dict.items():
   print(item)

The output of the above code is:

('AA', 11)
('CC', 33)
('BB', 22)
('DD', 44)

('AA', 11)
('BB', 22)
('CC', 33)
('DD', 44)

3. defaultdict

A defaultdict in Python collections works exactly like a normal dict, but it is initialized with a function (“default factory”) that takes no arguments and provides the default value for a nonexistent key.

A defaultdict will never raise a KeyError. Any key that does not exist gets the value returned by the default factory.

The following code explains the working of defaultdict:

from collections import defaultdict
ice_cream = defaultdict(lambda: 'Vanilla')
ice_cream['Sarah'] = 'Strawberry'
ice_cream['Abdul'] = 'Butter Pecan'
print ice_cream['Sarah']
print ice_cream['Joe']

The output of the above code is:

Strawberry
Vanilla

4. ChainMap

The ChainMap encapsulates several dictionaries into a single unit in Python collections. The maps are used to display the key-value pairs of all the dictionaries from the ChainMap. The keys() method returns the keys from the ChainMap, and the values() method returns the values of different keys from the ChainMap.

python collections

Following example shows the use of ChainMap:

from collections import ChainMap 
d1 = {'a': 1, 'b': 2}
d2 = {'c': 3, 'd': 4}
d3 = {'e': 5, 'f': 6}
# Defining the chainmap 
c = ChainMap(d1, d2, d3) 
# Accessing Values using key name
print(c['a'])
# Accessing values using values()
print(c.values())  
# Accessing keys using keys()
print(c.keys())

The output of the above code is:

1
ValuesView(ChainMap({‘a’: 1, ‘b’: 2}, {‘c’: 3, ‘d’: 4}, {‘e’: 5, ‘f’: 6}))
KeysView(ChainMap({‘a’: 1, ‘b’: 2}, {‘c’: 3, ‘d’: 4}, {‘e’: 5, ‘f’: 6}))

6. namedtuple

namedtuple in Python collections was created to improve code readability by providing a way to access values using descriptive field names instead of integer indices, which most of the time don’t provide any context on what the values are. This feature also makes the code cleaner and more maintainable.

In contrast, using indices to values in a regular tuple can be annoying, difficult to read, and error-prone. This is especially true if the tuple has a lot of fields and is constructed far away from where you’re using it.

In general, you can use namedtuple instances wherever you need a tuple-like object. Named tuples have the advantage that they provide a way to access their values using field names with the dot notation.

The following code demonstrates the advantage of using namedtuple:

from collections import namedtuple
# Declaring namedtuple() 
Student = namedtuple('Student',['name','age','DOB']) 
# Adding values 
S = Student('Rakesh','18','2542003') 
# Access using index 
print ("The Student age using index is : ",end ="") 
print (S[1]) 
# Access using name  
print ("The Student name using keyname is : ",end ="") 
print (S.name)

The output of the above code is:

The Student age using index is : 18
The Student name using keyname is : Rakesh

7. Deque

A double-ended queue, or Deque, in Python collections, has the feature of adding and removing elements from either end. It has the methods for adding and removing elements that can be invoked directly with arguments. 

The following code demonstrates the use of Deque:

import collections
# Create a deque
DoubleEnded = collections.deque(["Mon","Tue","Wed"])
print (DoubleEnded)
# Append to the right
print("Adding to the right: ")
DoubleEnded.append("Thu")
print (DoubleEnded)
# append to the left
print("Adding to the left: ")
DoubleEnded.appendleft("Sun")
print (DoubleEnded)
# Remove from the right
print("Removing from the right: ")
DoubleEnded.pop()
print (DoubleEnded)
# Remove from the left
print("Removing from the left: ")
DoubleEnded.popleft()
print (DoubleEnded)
# Reverse the dequeue
print("Reversing the deque: ")
DoubleEnded.reverse()
print (DoubleEnded)

The output of the above code is:

deque(['Mon', 'Tue', 'Wed'])
Adding to the right: 
deque(['Mon', 'Tue', 'Wed', 'Thu'])
Adding to the left: 
deque(['Sun', 'Mon', 'Tue', 'Wed', 'Thu'])
Removing from the right: 
deque(['Sun', 'Mon', 'Tue', 'Wed'])
Removing from the left: 
deque(['Mon', 'Tue', 'Wed'])
Reversing the deque: 
deque(['Wed', 'Tue', 'Mon'])

8. UserDict

Python collections provide us with a dictionary data structure to deal with a key-value from data. UserDict adds customization to it.

The dictionary helps us to create a data structure that holds key-value pairs in a static format. With UserDict, we can add some modified functionality by creating a customized dictionary.

It behaves like a wrapper class around the dictionary objects. By this, we can easily add new behaviour to the existing dictionary object.

The UserDict collection accepts the existing dictionary as an argument and triggers a dictionary structure that is stored in the usual dict object.

The following code demonstrates the use of UserDict:

from collections import UserDict
class mydata(UserDict):
	def pop(self, s = None):
		raise RuntimeError("Deletion not allowed")
mydict = mydata({'x':10,
    'y': 20})
print(mydict)
#Deleting From Dict
mydict.pop()

The output of the above code is:

{'x': 10, 'y': 20}
Traceback (most recent call last):
  File "/home/demo.py", line 15, in <module>
    mydict.pop()
  File "/home/demo.py", line 7, in pop  	
    raise RuntimeError("Deletion not allowed")
RuntimeError: Deletion not allowed

9. UserList

Like UserDict, UserList in Python collections also offers you a way to customize Lists in Python to be inculcated into classes. Python Lists stores similar types of data with different data types altogether. UserList helps you customize the list and use them as an attribute to create user-defined classes out of them. Having added the list as an instance, it triggers a list that is kept in the usual list data structure.

The following code demonstrates the use of UserList:

from collections import UserList 
# Creating a List where 
# deletion is not allowed 
class MyList(UserList): 
    # Function to stop deletion 
    # from List 
    def remove(self, s = None): 
        raise RuntimeError("Deletion not allowed") 
    # Function to stop pop from  
    # List 
    def pop(self, s = None): 
        raise RuntimeError("Deletion not allowed") 
# Driver's code 
L = MyList([1, 2, 3, 4]) 
print("Original List") 
# Inserting to List" 
L.append(5) 
print("After Insertion") 
print(L) 
# Deleting From List 
L.remove()

The output of the above code is:

Original List
After Insertion
[1, 2, 3, 4, 5]
Traceback (most recent call last):
  File "/home/UL.py", line 33, in <module>
    L.remove() 
  File "/home/UL.py", line 15, in remove
    raise RuntimeError("Deletion not allowed") 
RuntimeError: Deletion not allowed

Conclusion: In the Python collections module, you have several specialized container data types that you can use to approach common programming problems, such as counting objects, creating queues and stacks, handling missing keys in dictionaries, and more. The data types and classes in collections were designed to be efficient. They can be tremendously helpful in your Python programming journey, so learning about them is well worth your time and effort.

{"email":"Email address invalid","url":"Website address invalid","required":"Required field missing"}
>