Dictionaries: Power & Speed
In Python, everything is a dictionary. Modules, classes, namespaces—it's all hash maps all the way down. Understanding the Dictionary is understanding Python itself.
A dict (Hash Map) is the most optimized data structure in Python. It maps unique Keys to Values.
Historically, dictionaries were unordered and memory-hungry. But in the Python 3.6+ era, a revolution called the "Compact Dict" changed everything. They are now ordered by insertion and use ~30% less RAM.
What You'll Learn
- Modern Internals: How "Compact Dicts" work (Indices Array vs Entries Array).
- Safe Access: Why
.get()is better than brackets. - Merging: The modern
|operator (Python 3.9+). - Performance: O(1) average lookup speed.
The Revolution: Compact Dicts
Before Python 3.6, a dictionary was a sparse table with lots of empty space. Now, Python splits simple storage into two parts:
- Indices Array: A small table mapping hash-to-index.
- Entries Array: A dense list of
(hash, key, value)tuples.
This is why d = {"a": 1, "b": 2} remembers that "a" came before "b". It's not just a side effect anymore; it's a language guarantee.
Accessing Patterns: Safe vs Unsafe
The most common error in beginner Python code is KeyError. This happens when you assume data exists when it doesn't.
user_data = {"id": 4209, "name": "Rohit"}
# ⌠Unsafe: If 'email' is missing, the program CRASHES
# print(user_data["email"])
# Output: KeyError: 'email'
# ✅ Safe: Returns None if missing
email = user_data.get("email")
# ✅ Safer: Returns a default value
role = user_data.get("role", "Guest")
print(f"Role: {role}") # Output: Role: GuestMerging Dictionaries (The Modern Way)
Merging configs or JSON responses is common. Python 3.9 gave us the beautiful Union Operator |.
default_config = {"theme": "dark", "notifications": True}
user_config = {"theme": "light"}
# The RIGHT side overwrites the LEFT side
final_config = default_config | user_config
print(final_config)
# {'theme': 'light', 'notifications': True}{**d1, **d2}. This is the "dictionary unpacking" hack. It works, but | is cleaner.Valid Keys: Hashability Rule
Just like Sets, Dictionary Keys must be immutable (hashable). Values can be anything.
# ✅ Valid
d = {
(1, 2): "Coordinate", # Tuple is immutable
"name": "String" # String is immutable
}
# ⌠Invalid
d = {
[1, 2]: "List" # List is mutable -> CRASH
}Best Practices & Takeaways
✅ Do
- Use
.get()for optional keys. - Use
.items()to loop over key-value pairs at once. - Use
dict | dictto merge.
⌠Don't
- Don't check
if key in d:then accessd[key]. Just used.get()! - Don't modify a dict size while looping over it.