The collections module in Python provides alternatives to the built-in data types (like list, dict, set, and tuple) and introduces specialized container datatypes that can enhance functionality and improve code efficiency. It was introduced in Python 2.4 and has been a valuable addition for more advanced data handling and manipulation.
Here's an overview of the key components in the collections module:
The namedtuple() function creates tuple-like objects with named fields. This enhances readability by allowing you to access tuple elements using named attributes rather than positional indexing.
from collections import namedtuple
# Define a namedtuple type
Person = namedtuple('Person', ['name', 'age', 'city'])
# Create an instance of Person
person = Person(name='Alice', age=30, city='New York')
# Access fields by name
print(person.name) # Output: Alice
print(person.age) # Output: 30
print(person.city) # Output: New York
• Improved code readability
• Named fields make code self-documenting
• Supports tuple-like immutability
The OrderedDict() maintains the order of keys based on their insertion order. Unlike a regular dictionary (in Python versions prior to 3.7), it ensures that the order of items remains consistent.
from collections import OrderedDict
# Create an OrderedDict
ordered_dict = OrderedDict()
ordered_dict['apple'] = 1
ordered_dict['banana'] = 2
ordered_dict['cherry'] = 3
# Print the dictionary items in insertion order
for key, value in ordered_dict.items():
print(key, value)
• Maintains the order of insertion
• Useful when order is important for processing or output
The defaultdict() is a subclass of dict that provides a default value for missing keys. You can specify a default factory function, which returns the default value for new keys.
from collections import defaultdict
# Create a defaultdict with default value as list
default_dict = defaultdict(list)
# Append values to the list for each key
default_dict['fruits'].append('apple')
default_dict['fruits'].append('banana')
# Access a key that does not exist
print(default_dict['vegetables']) # Output: []
# Add new key-value pair
default_dict['vegetables'].append('carrot')
print(default_dict['vegetables']) # Output: ['carrot']
• Avoids key errors by providing default values
• Simplifies code for handling missing keys
The Counter() class counts the occurrences of hashable objects. It's a specialized dictionary for counting elements and provides additional functionality to interact with counts.
from collections import Counter
# Create a Counter object
counter = Counter(['apple', 'banana', 'apple', 'orange', 'banana', 'banana'])
# Print counts of each item
print(counter) # Output: Counter({'banana': 3, 'apple': 2, 'orange': 1})
# Access count of a specific item
print(counter['apple']) # Output: 2
• Efficiently counts occurrences of elements
• Provides methods for common statistical operations
The ChainMap() class groups multiple dictionaries or mappings into a single view. It's useful for managing multiple contexts or layers of mappings.
from collections import ChainMap
# Create some dictionaries
dict1 = {'a': 1, 'b': 2}
dict2 = {'b': 3, 'c': 4}
# Create a ChainMap
chain_map = ChainMap(dict1, dict2)
# Access items from the combined view
print(chain_map['a']) # Output: 1
print(chain_map['b']) # Output: 2 (from the first dictionary)
print(chain_map['c']) # Output: 4
• Combines multiple dictionaries into a single view
• Useful for managing hierarchical data or configurations
UserDict is a wrapper around dictionary objects, allowing you to create custom dictionary-like classes with additional or modified functionality.
from collections import UserDict
class MyDict(UserDict):
def __setitem__(self, key, value):
print(f'Setting {key} = {value}')
super().__setitem__(key, value)
# Create an instance of MyDict
my_dict = MyDict()
my_dict['name'] = 'Alice' # Output: Setting name = Alice
• Allows customization of dictionary behavior
• Provides a way to extend or modify dictionary functionality
UserList is a wrapper around list objects, providing a way to create custom list-like classes with additional or modified functionality.
from collections import UserList
class MyList(UserList):
def append(self, item):
print(f'Appending {item}')
super().append(item)
# Create an instance of MyList
my_list = MyList()
my_list.append('hello') # Output: Appending hello
• Allows customization of list behavior
• Useful for extending or modifying list functionality
UserString is a wrapper around string objects, providing a way to create custom string-like classes with additional or modified functionality.
from collections import UserString
class MyString(UserString):
def __str__(self):
return f'Custom String: {self.data}'
# Create an instance of MyString
my_string = MyString('hello')
print(my_string) # Output: Custom String: hello
• Allows customization of string behavior
• Useful for extending or modifying string functionality