ReviseAlgo Logo

Dictionaries

DefaultDict

Dictionaries with automatic default values for missing keys

Interview: Extremely common in coding interviews for counting, grouping, and graph algorithms

Last Updated: June 12, 2026 10 min read

defaultdict is a subclass of dict from the collections module that automatically creates a default value for missing keys using a factory function. It eliminates the need for repetitive "if key in dict" checks and is one of the most useful tools in a Python programmer's toolkit.

How defaultdict Works

When you access a key that doesn't exist, defaultdict calls its default_factory function to create a default value, inserts it into the dict, and returns it:

  • Factory function: Passed as the first argument — defaultdict(int), defaultdict(list), etc.
  • __missing__ method: defaultdict overrides this dict method to call the factory — regular dicts raise KeyError
  • Only triggered on access: The factory is called only on __getitem__ (d[key]), NOT on .get(), .setdefault(), or 'in' checks
  • Subclass of dict: All regular dict methods work identically — isinstance(dd, dict) is True

Common Factory Functions

  • int (default: 0): Perfect for counting — dd["x"] += 1 works without initialization
  • list (default: []): Perfect for grouping — dd[group].append(item)
  • set (default: set()): For collecting unique items per group — dd[group].add(item)
  • float (default: 0.0): For accumulating decimal values
  • str (default: ""): For string concatenation per key
  • Custom lambda: defaultdict(lambda: {"count": 0, "total": 0}) for complex defaults

defaultdict vs dict.get() vs dict.setdefault()

defaultdict: best when you access missing keys frequently and always want the same default type. dict.get(key, default): best for one-off safe access (doesn't store the default). dict.setdefault(key, default): stores the default but creates a new object each call — use defaultdict instead for repeated patterns.

Advanced Patterns

  • Nested defaultdict: tree = lambda: defaultdict(tree) creates an auto-vivifying tree structure
  • Counter replacement: defaultdict(int) works like Counter but with more control over the counting logic
  • Graph adjacency lists: defaultdict(list) is the standard representation for undirected/directed graphs
  • Multidict: defaultdict(list) stores multiple values per key — useful for inverted indexes

Common Pitfall: Accidental Key Creation

Accessing a missing key with dd[key] creates it with the default value. This can silently add unwanted keys. Use key in dd to check existence first, or use dd.get(key) which returns None without creating a key.

Converting Back to Regular Dict

When you need a regular dict (for serialization, comparison, or API responses), convert with dict(dd) for top-level or a recursive function for nested defaultdicts.

Use Cases

Counting occurrences without initializing each key first

Grouping items by a key (employees by department, words by first letter)

Building graph adjacency lists for BFS, DFS, and shortest path algorithms

Creating inverted indexes (searching by value to find keys)

Accumulating totals per category in data processing pipelines

Common Mistakes

Accessing dd[key] to check existence — this creates the key with default value; use "key in dd" instead

Passing a value instead of a factory: defaultdict(0) raises TypeError — use defaultdict(int)

Forgetting that .get() does NOT trigger the factory — it returns None for missing keys

Using mutable defaults with lambda incorrectly — defaultdict(lambda: []) works, but the lambda is called per key

Not converting defaultdict back to dict when serializing to JSON or comparing with regular dicts