ASAmol Shukla
Projects
Courses
Prompts
Skills
Contact
Resume
Course Outline
Syllabus Overview

Complete Python Course: From Zero to Professional

Courses/Complete Python Course: From Zero to Professional/Lesson 10: Advanced Collections — Counter, defaultdict & deque
40 mins lesson duration•8 mins read

Lesson 10: Advanced Collections — Counter, defaultdict & deque

Supercharge your data with Counter, defaultdict, deque, and namedtuple from the collections module.

The collections Module — Professional Tools

The collections module ships with specialized containers that solve common problems in one line. Once you know them, you will wonder how you lived without them. This lesson covers the four you will use constantly.

These containers are pure Python's answer to the "I keep writing the same boilerplate" problem — every one of them replaces several lines of manual logic with a single, readable construction.

What You'll Learn in This Lesson

  • Tally anything instantly with Counter
  • Stop fearing missing keys with defaultdict
  • Build fast queues with deque
  • Create self-documenting records with namedtuple

Counter — Instant Tallies

Counter counts hashable items and gives you .most_common() for free:

from collections import Counter

votes = ["python", "python", "ai", "ml", "ai", "ai"]
tally = Counter(votes)
print(tally)                    # Counter({'ai': 3, 'python': 2, 'ml': 1})
print(tally.most_common(2))     # [('ai', 3), ('python', 2)]

It also works on any iterable — including strings (counts characters):

print(Counter("mississippi").most_common(1))  # [('s', 4)]

Mental model: a tally sheet where every item adds one tick.

Useful Counter operations:

Operation Code Result for votes above
Total count sum(tally.values()) 6
Most common n tally.most_common(2) [('ai', 3), ('python', 2)]
Add two counters tally + Counter(["ai"]) {'ai': 4, ...}
Top item tally.most_common(1)[0][0] 'ai'

Counters power frequency analysis in everything from word clouds to vote counting to sales reports.


defaultdict — Never Fear Missing Keys

A normal dict raises KeyError on missing keys. A defaultdict returns a default value instead — automatically creating the entry:

from collections import defaultdict

teams = defaultdict(list)
teams["IT"].append("Amol")   # no KeyError — key auto-created!
teams["IT"].append("Sam")
teams["HR"].append("Riya")
print(dict(teams))   # {'IT': ['Amol', 'Sam'], 'HR': ['Riya']}

The argument to defaultdict is a factory — a function that creates the default:

Factory Default value
defaultdict(list) []
defaultdict(int) 0
defaultdict(set) set()
defaultdict(dict) {}

This removes endless if key not in dict: boilerplate — ideal when grouping data.

Compare the two styles:

# Manual — 4 lines of ceremony per group
groups = {}
for dept, name in employees:
    if dept not in groups:
        groups[dept] = []
    groups[dept].append(name)

# defaultdict — 3 lines total, no ceremony
groups = defaultdict(list)
for dept, name in employees:
    groups[dept].append(name)

deque — Fast Operations on Both Ends

A deque (double-ended queue) gives O(1) append/pop on both ends. Lists are O(n) for left-side operations; deques are instant:

from collections import deque

queue = deque(["a", "b"])
queue.append("c")        # add to right end
queue.appendleft("z")    # add to left end
queue.popleft()          # remove from left
print(list(queue))       # ['a', 'b', 'c']
List deque
Append right O(1) O(1)
Pop left / insert left O(n) O(1)
Random access O(1) O(n)

Use deque for queues, recent-history buffers, and any structure needing fast left-end operations. deque(maxlen=100) auto-drops the oldest item — a rolling buffer.

Mental model: a deque is a train with doors at both ends — boarding and leaving is instant at either end, unlike a list where people at the front must shuffle over.


namedtuple — Self-Documenting Data

namedtuple creates lightweight objects with named fields — cleaner than a plain tuple, lighter than a class:

from collections import namedtuple

Point = namedtuple("Point", ["x", "y"])
p = Point(3, 4)
print(p.x, p.y)     # 3 4  — access by name
print(p[0])         # 3   — still works by index

Perfect for coordinates, records, and configuration — you get readability without writing a full class.

namedtuple vs dataclass: if you need just named fields with no methods, namedtuple is ideal. If you want defaults, validation, or methods, the @dataclass decorator (Lesson 19) is the modern choice.


Common Mistakes to Avoid

  • Mistake: Passing an unhashable (like a list) to Counter — Fix: Counter needs hashable items.
  • Mistake: Reading from a defaultdict and unintentionally creating keys — Fix: use defaultdict only for writes, or use .get() when reading counts.
  • Mistake: queue[0] style random access on a huge deque — Fix: deques are for ends; use a list for random access.
  • Mistake: Using a plain dict and re-writing the if key not in ceremony — Fix: reach for defaultdict when grouping.
  • Mistake: namedtuple field names that clash with keywords (e.g. class) — Fix: rename the field (cls).

Professional Tips & Tricks

  • most_common(n) turns 'analyze frequencies' into one line.
  • defaultdict(list) is the go-to for grouping — dict comprehension of lists, without boilerplate.
  • Use deque(maxlen=100) for a rolling buffer that auto-drops the oldest item.
  • Use namedtuple for return values that should be readable at a glance.
  • Counters support arithmetic (+ , - ) — combine tallies from different sources.

Key Takeaways

  • Counter tallies items and ranks them with .most_common().
  • defaultdict(factory) auto-creates missing keys.
  • deque gives O(1) operations on both ends — the right tool for queues.
  • namedtuple gives named fields with tuple performance.
  • deque(maxlen=n) makes rolling buffers effortless.

Next up: Nested structures, aliasing & copies — where beginners lose hours.

Interactive Lesson Code Snippet
from collections import Counter, defaultdict, deque, namedtuple

# Counter: tally votes
votes = ["python", "python", "ai", "ml", "ai", "ai"]
tally = Counter(votes)
print("Tally:", tally)
print("Top 2:", tally.most_common(2))

# defaultdict: group by department
employees = [("IT", "Amol"), ("HR", "Riya"), ("IT", "Sam")]
teams = defaultdict(list)
for dept, name in employees:
    teams[dept].append(name)
print("Teams:", dict(teams))

# deque: fast queue
queue = deque(["a", "b"])
queue.append("c")
queue.popleft()
print("Queue:", list(queue))

# namedtuple: readable records
Point = namedtuple("Point", ["x", "y"])
p = Point(3, 4)
print("Point:", p.x, p.y)
Language: python

Lesson Code (Python)

from collections import Counter, defaultdict, deque, namedtuple

# Counter: tally votes
votes = ["python", "python", "ai", "ml", "ai", "ai"]
tally = Counter(votes)
print("Tally:", tally)
print("Top 2:", tally.most_common(2))

# defaultdict: group by department
employees = [("IT", "Amol"), ("HR", "Riya"), ("IT", "Sam")]
teams = defaultdict(list)
for dept, name in employees:
    teams[dept].append(name)
print("Teams:", dict(teams))

# deque: fast queue
queue = deque(["a", "b"])
queue.append("c")
queue.popleft()
print("Queue:", list(queue))

# namedtuple: readable records
Point = namedtuple("Point", ["x", "y"])
p = Point(3, 4)
print("Point:", p.x, p.y)

Console Output

Tally: Counter({'ai': 3, 'python': 2, 'ml': 1})
Top 2: [('ai', 3), ('python', 2)]
Teams: {'IT': ['Amol', 'Sam'], 'HR': ['Riya']}
Queue: ['b', 'c']
Point: 3 4

Code Visualization Tips

  • 🧠Picture Counter as a tally sheet where every item adds one tick.
  • 🧠Visualize defaultdict as a table that auto-fills an empty cell with a default the first time it is touched.
  • 🧠Draw a deque as a train with doors at both ends — boarding and leaving is instant at either end.

Professional Tips & Tricks

  • ⚡most_common(n) turns 'analyze frequencies' into one line.
  • ⚡defaultdict(list) is the go-to for grouping — dict comprehension of lists, without boilerplate.
  • ⚡Use deque(maxlen=100) for a rolling buffer that auto-drops the oldest item.

Python Code Judge & Practice Arena

LeetCode Style

Run real Python 3.12 WebAssembly code directly in your browser against automated test suites.

Solved:0 / 20
0 / 370 XP
Challenges:
Problem 1 of 20

Problem 1: Top-K Frequent Elements 1

Easy+10 XP
Write a function `top_k_frequent_1(items, k=2)` using collections.Counter that returns a list of the top k most common elements.
Sample Test Cases:
Input: top_k_frequent_1(['a', 'b', 'a', 'c', 'a', 'b'], 2)
Expected: ['a', 'b']
Input: top_k_frequent_1([1, 2, 2, 3], 1)
Expected: [2]
main.pyPython 3.12 (WASM)
1
2
3
4
5
6
7
8
9
10
11
12
Press Run Code to test or Submit to verify test cases

Test Your Knowledge

Instant feedback

Quick Check: Lesson 10: Advanced Collections: defaultdict, Counter, deque & namedtuple

1 / 20
What does this `defaultdict(list)` code output? from collections import defaultdict d = defaultdict(list) d['fruits'].append('apple') print(d['fruits'], d['vegetables'])

Up next · Continue learning

Nested Structures, Aliasing & Copies

Build nested dicts and lists, understand how references behave, and copy safely.

8 mins read40 mins
Start next lesson
Previous: Sets & DictionariesNext: Nested Structures, Aliasing & Copies
Made withbyAmol Shukla·amolshukla.online
ASAmol Shukla

AI Developer, Trainer & Agentic AI Expert building practical learning systems and real-world AI applications.

Explore

  • Projects
  • Courses
  • Prompts
  • Skills
  • Contact
  • Experience
  • Blogs

Connect

  • Resume
  • Contact
© 2026 Amol Shukla·Created withbyamolshukla.online
Back to top