advanced

Collections, Heapq & Itertools

7 min readLast updated: 2026-07-12

Overview

Advanced collections (Counter, defaultdict, deque), priority heaps, and itertools speed up complex data operations.

Learning Objectives

  • Group records using collections.defaultdict.
  • Find Top-K elements using priority queues (heapq).
  • Write lazy iterator chains using itertools.

Concept Explanation

The collections module provides structures like Counter (tallying frequencies), defaultdict (safe defaults), and deque (fast O(1) pops). heapq implements priority queues. itertools provides memory-efficient iterators.

Code Examples

Example 1 — Basics

This example introduces the fundamental syntax and concepts.

python
from collections import Counter
c = Counter('abacaba')
print(c['a']) # 4

Example 2 — Everyday Usage

This example demonstrates a realistic scenario handling business parameters.

python
import heapq
scores = [12, 3, 45, 9, 30]
# Retrieve top 3 scores
top_three = heapq.nlargest(3, scores)
print(top_three)

Example 3 — Advanced Example

This example shows clean, production-grade code structure following senior development standards.

python
from collections import defaultdict
import itertools

def group_anagrams(words):
    # Group sorted letter keys to original words
    grouped = defaultdict(list)
    for w in words:
        sorted_key = ''.join(sorted(w))
        grouped[sorted_key].append(w)
    return list(grouped.values())

print(group_anagrams(['eat', 'tea', 'tan', 'nat', 'bat']))

Visual Flow

The following execution flow represents the step-by-step evaluation inside the interpreter:

text
Unsorted List → heapify() → Construct Binary Min-Heap → heappop() → Retrieve Smallest Element in O(log N)

Common Mistakes

Review these common pitfalls when working with this topic:

  • Using list.pop(0) instead of deque.popleft(), slowing down queue operations to O(N).
  • Expecting heapq to maintain a sorted list internally (heaps are binary trees, not sorted lists).
  • Forgetting that itertools iterators are exhausted after a single use.
  • Negating values in heapq manually without using type safe helpers for custom comparisons.

Best Practices

Enforce these Pythonic best practices in your codebase:

❌ Don't
python
q = []
q.append(x)
q.pop(0) # Slow O(N) queue pops
✅ Do
python
from collections import deque
q = deque()
q.append(x)
q.popleft() # Fast O(1) queue pops

Performance Notes

Keep these optimization guidelines in mind for performance-sensitive hotpaths:

  • collections.deque has O(1) append and pop complexity on both ends.
  • heapq.heappush() and heapq.heappop() run in O(log N) logarithmic time.
  • itertools chain() combines iterables without copying their elements in memory.

Quick Revision

Use these key summaries for last-minute revision:

  • Counter tallies frequency counts.
  • defaultdict prevents KeyError lookups.
  • deque provides fast O(1) double-ended pops.
  • heapq implements binary min-heaps.
  • Heaps run pushes/pops in O(log N).
  • itertools supports lazy loop combinations.