Chapter 8 of 21
Lists & Tuples
Current Study Module
Dictionaries & Sets
Modules, Packages & Pip
Chapter 07 • Hash-Based Data Structures

Dictionaries & Sets: Hash Tables & Set Theory

Dictionaries are the heart of Python—internal object namespaces, global scopes, and class attributes are all powered by hash tables. Learn how CPython achieves lightning-fast O(1) key lookups, how compact dictionaries preserve insertion order, and how sets execute mathematical operations.

1. CPython Hash Table Architecture

A dictionary maps keys to values by running the key through a hash function (hash(key)). The resulting integer hash is masked to index into a sparse array of buckets.

The Hashability Contract: For an object to serve as a dictionary key or set element, it must be hashable: it must implement __hash__() (returning an integer that never changes during its lifetime) and __eq__(). All immutable built-in types (strings, ints, frozensets, tuples of hashables) are hashable; mutable lists and dicts are not!

2. Modern Dictionary Operations & The Union Operator (|)

Python 3.9+ introduced the pipe operator (|) for clean dictionary merging (PEP 584):

# Base configuration defaults
default_config = {"theme": "light", "timeout": 30, "retries": 3}
user_overrides = {"theme": "dark", "retries": 5}

# 1. Merge dictionaries with right-side precedence using |
merged_config = default_config | user_overrides
print(merged_config)  # {'theme': 'dark', 'timeout': 30, 'retries': 5}

# 2. In-place merge update using |=
default_config |= {"debug": True}

# 3. Safe key extraction with default fallback
api_port = default_config.get("port", 8080)  # Returns 8080 without KeyError!

# 4. setdefault for grouping
grouped_data = {}
for user, role in [("Alice", "Admin"), ("Bob", "Viewer"), ("Charlie", "Admin")]:
    grouped_data.setdefault(role, []).append(user)

print("Grouped by role:", grouped_data)

3. Sets & Mathematical Set Theory Operations

A set is an unordered collection of unique hashable elements. Because membership testing operates in O(1) time, checking x in my_set is thousands of times faster than x in my_list for large datasets!

backend_engineers = {"Alice", "Bob", "Charlie", "David"}
frontend_engineers = {"Charlie", "David", "Eve", "Frank"}

# Union (|): All unique engineers across both teams
print("Union:", backend_engineers | frontend_engineers)

# Intersection (&): Full-stack engineers on both teams
print("Intersection:", backend_engineers & frontend_engineers)  # {'Charlie', 'David'}

# Difference (-): Backend engineers who do NOT touch frontend
print("Difference:", backend_engineers - frontend_engineers)    # {'Alice', 'Bob'}

# Symmetric Difference (^): Engineers on ONE team, but not both
print("Symmetric Difference:", backend_engineers ^ frontend_engineers)

4. Immutable Sets: frozenset

Standard sets cannot be used as dictionary keys because they are mutable. Use frozenset to create an immutable, hashable set:

# Using frozenset as a cache key in graph routing
route_cache = {}

path_a = frozenset(["node_1", "node_2", "node_3"])
route_cache[path_a] = 45.2  # Latency in ms

print(f"Cached route latency: {route_cache[path_a]} ms")

Explore Related Tools

Hand-picked utilities and calculators related to this tool.

Related Tools