Python Dictionaries
Dictionary (dict) is one of the most powerful and efficient data structures. Unlike Lists, which use numbers (indexes) to access data, Dictionaries use Keys.
Think of a Real Dictionary: If you want to know the meaning of “Python”, you look up the word “Python” (the Key) to find its definition (the Value). You don’t read every page; you jump straight to the word. This makes dictionaries incredibly fast.
1. Key Characteristics
- Key-Value Pairs: Data is stored as key: value.
- Unordered (Pre-3.7) / Ordered (3.7+): Modern Python remembers the order in which items were inserted.
- Mutable: You can change, add, or delete items after creation.
- Unique Keys: Duplicate keys are not allowed. If you repeat a key, the last one overwrites the previous ones.
- Dynamic: It grows and shrinks automatically as needed.
2. Creating a Dictionary
1. Standard Syntax {}
The most common method using curly braces.
user = {
"name": "John Doe",
"age": 25,
"skills": ["Python", "Linux"], # Value can be a List
"is_active": True
}2. The dict() Constructor
Useful for cleaner syntax when keys are simple strings.
# Keys are written as parameters (no quotes needed)
config = dict(host="localhost", port=8080, db="users")3. Nested Dictionaries
A dictionary inside another dictionary (e.g., typical JSON data).
employees = {
"emp01": {"name": "Alice", "salary": 5000},
"emp02": {"name": "Bob", "salary": 7000}
}3. Accessing Data
1. Using .get()
Returns None (or a custom default) if the key is missing, preventing crashes.
print(data.get("color")) # Output: None
print(data.get("color", "Red")) # Output: Red (Custom default)2. Using Square Brackets []
Fast and direct, but risky.
data = {"brand": "Ford", "model": "Mustang"}
print(data["model"]) # Output: Mustang- If the key doesn’t exist (e.g., data[“color”]), Python raises a KeyError and crashes the program.
4. Modifying Dictionaries (CRUD)
Adding & Updating
If the key exists, it updates the value. If not, it creates a new entry.
car = {"brand": "Ford"}
# Adding
car["year"] = 2024
# Updating
car["brand"] = "BMW"
# Bulk Update (Merging)
car.update({"brand": "Audi", "color": "Blue"})Removing Items
| Method | Description | Example |
| .pop(key) | Removes key & returns its value. | val = car.pop(“year”) |
| .popitem() | Removes the last inserted item. | car.popitem() |
| del dict[key] | Deletes the key from memory. | del car[“brand”] |
| .clear() | Empties the dictionary completely. | car.clear() |
5. Looping – Iteration
You can loop through keys, values, or both.
data = {"A": 10, "B": 20}
# 1. Loop Keys
for k in data:
print(k) # A, B
# 2. Loop Values
for v in data.values():
print(v) # 10, 20
# 3. Loop Both (Most Common)
for k, v in data.items():
print(f"{k} -> {v}")6. Dictionary Methods
| Method | Description | Example |
| keys() | Returns a view of all keys. | d.keys() |
| values() | Returns a view of all values. | d.values() |
| items() | Returns list of (key, value) tuples. | d.items() |
| get(k) | Safe access. Returns None if missing. | d.get(“id”) |
| pop(k) | Removes key and returns value. | d.pop(“id”) |
| update(d) | Merges another dict into this one. | d.update({“x”: 1}) |
| copy() | Returns a shallow copy. | new_d = d.copy() |
| setdefault() | Returns value if exists; inserts if not. | d.setdefault(“k”, 0) |
7. The “Hashable” Key Rule
- Allowed Keys: Immutable types (Strings, Integers, Tuples, Booleans).
- Forbidden Keys: Mutable types (Lists, Dictionaries).
Python calculates a unique “hash” (fingerprint) for every key to look it up instantly. Mutable objects change, meaning their fingerprint would change, breaking the lookup system.
valid = { (10, 20): "Point A" } # Tuple is immutable
# invalid = { [10, 20]: "Point B" } # Error: unhashable type: 'list'8. Dictionary Comprehension
Create dictionaries concisely in one line.
Syntax: {key: value for var in iterable}
# Create a dict of squares: {1: 1, 2: 4, 3: 9...}
squares = {x: x**2 for x in range(1, 6)}9. Handling Missing Keys defaultdict
Instead of checking if key in dict constantly, use defaultdict. It automatically creates a default value when a missing key is accessed.
- Requires from collections import defaultdict
from collections import defaultdict
# A dict that defaults to 0 (useful for counting)
counts = defaultdict(int)
words = ["apple", "banana", "apple"]
for word in words:
counts[word] += 1 # No KeyError! Automatically starts at 0.
print(dict(counts)) # {'apple': 2, 'banana': 1}10. Merging Dictionaries | Operator
The cleanest way to combine two dictionaries.
x = {"a": 1, "b": 2}
y = {"b": 3, "c": 4}
merged = x | y
print(merged)
# Output: {'a': 1, 'b': 3, 'c': 4}
# Note: Value from the second dict ('b': 3) wins.11. Sorting Dictionaries
Dictionaries are mappings, not lists, so they don’t have a .sort() method. To display them in order, use the sorted() function.
scores = {"Alice": 85, "Bob": 92, "Charlie": 78}
# Sort by Value (Score) - High to Low
sorted_scores = dict(sorted(scores.items(), key=lambda item: item[1], reverse=True))
print(sorted_scores) # {'Bob': 92, 'Alice': 85, 'Charlie': 78}12. Performance Secrets
Why are dictionaries so popular? Speed.
- List Lookup: Python scans items one by one. If you have 1 million items, it checks up to 1 million times (list(n)).
- Dictionary Lookup: Python uses the Hash to jump directly to the memory address. Whether you have 10 items or 10 million, the lookup time is nearly instantaneous map(1).
13. Deep vs. Shallow Copy
A standard .copy() is shallow. If your dictionary contains lists, modifying the list in the copy will affect the original.
For a truly independent clone, use Deep Copy.
import copy
original = {"ids": [1, 2, 3]}
# 1. Shallow Copy (Risky for nested data)
shallow = original.copy()
# 2. Deep Copy (Safe)
deep = copy.deepcopy(original)