← Back to Chapters

Python Collections Module

? Python Collections Module

⚡ Quick Overview

Python's collections module provides a set of high-performance, specialized container datatypes that extend the built-in data structures like list, tuple, and dict. They help write cleaner, more readable, and often faster code.

In this topic, we focus on: namedtuple, deque, Counter, defaultdict, OrderedDict, and ChainMap.

? Key Concepts

  • namedtuple – Tuple-like objects with named fields (access by name instead of index).
  • deque – Double-ended queue optimized for fast appends and pops from both ends.
  • Counter – Multiset / frequency counter for hashable objects.
  • defaultdict – Dictionary with a default value factory to avoid KeyError.
  • OrderedDict – Dictionary that remembers insertion order (important in older Python versions).
  • ChainMap – Logical grouping of multiple dictionaries into a single view.

? Syntax and Theory

? namedtuple

namedtuple(typename, field_names) creates a new tuple subclass with named fields. You can access elements using dot notation instead of numeric indexes.

Common use-cases: representing simple records like points, database rows, or configuration values.

? deque

deque(iterable, maxlen=None) creates a double-ended queue. It supports operations like append, appendleft, pop, and popleft in O(1) time.

Ideal for queues, BFS, sliding windows, and scenarios with heavy pushing/popping at both ends.

? Counter

Counter(iterable) counts occurrences of elements and stores them in a dictionary-like object where keys are elements and values are their counts.

Useful for frequency analysis (e.g., most common words, characters, or items).

? defaultdict

defaultdict(default_factory) automatically creates default values for missing keys using default_factory (like int, list, or dict).

This avoids repetitive existence checks and KeyError exceptions.

⚙️ OrderedDict

OrderedDict() acts like a normal dictionary but remembers the insertion order of keys. In modern Python (3.7+), normal dicts also preserve insertion order, but OrderedDict still provides extra methods like move_to_end.

? ChainMap

ChainMap(*maps) groups multiple mappings into a single view. When you access a key, it searches each mapping in order until it finds it.

Useful for layering configurations (e.g., defaults, env overrides, CLI args).

? Code Examples

? namedtuple Example

? View namedtuple Example
from collections import namedtuple

Point = namedtuple('Point', ['x', 'y'])

p = Point(10, 20)
print(p.x, p.y)  # Access via field names

? deque Example

? View deque Example
from collections import deque

dq = deque([1, 2, 3])
dq.appendleft(0)   # [0, 1, 2, 3]
dq.append(4)       # [0, 1, 2, 3, 4]
dq.pop()           # removes 4  → [0, 1, 2, 3]
dq.popleft()       # removes 0  → [1, 2, 3]

print(dq)

? Counter Example

? View Counter Example
from collections import Counter

data = ['a', 'b', 'c', 'a', 'b', 'a']
count = Counter(data)

print(count)          # Counter({'a': 3, 'b': 2, 'c': 1})
print(count['a'])     # 3
print(count.most_common(1))  # [('a', 3)]

? defaultdict Example

? View defaultdict Example
from collections import defaultdict

d = defaultdict(int)   # default value 0 for missing keys

d['a'] += 1
d['b'] += 2

print(d)           # defaultdict(<class 'int'>, {'a': 1, 'b': 2})
print(d['c'])      # 0 (auto-created, no KeyError)

⚙️ OrderedDict Example

? View OrderedDict Example
from collections import OrderedDict

od = OrderedDict()
od['a'] = 1
od['b'] = 2
od['c'] = 3

print(od)  # Maintains insertion order
od.move_to_end('a')
print(od)  # 'a' moved to the end

? ChainMap Example

? View ChainMap Example
from collections import ChainMap

defaults = {'theme': 'light', 'page_size': 10}
env = {'page_size': 20}
user = {'theme': 'dark'}

settings = ChainMap(user, env, defaults)

print(settings['theme'])     # 'dark'  (from user)
print(settings['page_size']) # 20      (from env)

? What These Examples Print

  • namedtuple: print(p.x, p.y)10 20
  • deque: after a series of operations, dq becomes deque([1, 2, 3]).
  • Counter: Counter({'a': 3, 'b': 2, 'c': 1}) plus handy methods like most_common().
  • defaultdict: missing keys like 'c' return 0 instead of raising KeyError.
  • OrderedDict: preserves insertion order and lets you reorder keys with move_to_end().
  • ChainMap: keys are resolved from left to right: user → env → defaults.

? Practical Tips

  • Use Counter whenever you need frequency counts instead of manually building dictionaries.
  • Prefer deque over lists for queue/stack patterns with heavy front operations.
  • Use defaultdict(list) or defaultdict(int) to simplify aggregation logic.
  • In modern Python, a normal dict preserves insertion order, but use OrderedDict if you need its extra methods or explicit ordering semantics.
  • Use ChainMap to layer configuration sources instead of manually merging dictionaries.

? Practice Tasks

  • Build a Counter from a string and print the three most common characters using most_common(3).
  • Use deque to implement a simple queue with enqueue (append) and dequeue (popleft). Test it with several elements.
  • Create a defaultdict(list) and group student names by their grade (e.g., keys as grades, values as lists of names).
  • Simulate configuration layers using ChainMap: defaults, environment variables, and user settings. Print which layer each setting came from.
  • Experiment with OrderedDict and the move_to_end() method to reorder menu items in a CLI app.