Dictionaries & Comprehensions
Dictionaries & Comprehensions
Dictionaries
A dictionary maps unique keys to values. In Python 3.7+ dictionaries preserve insertion order.
person = {"name": "Alice", "age": 30, "city": "NYC"}
empty = {}
also_valid = dict(name="Bob", age=25)Keys must be hashable (strings, numbers, tuples). Values can be anything.
Essential Dictionary Methods
| Method | Description |
|---|---|
d[key] | Get value; raises KeyError if missing |
d.get(key, default) | Get value; returns default if missing |
d[key] = val | Set or update a key |
d.update(other) | Merge another dict (or kwargs) in-place |
d.pop(key) | Remove key and return its value |
d.keys() | View of all keys |
d.values() | View of all values |
d.items() | View of (key, value) pairs |
d.setdefault(k, v) | Insert key with value v if key is absent |
key in d | Membership test (O(1)) |
Merging Dicts (Python 3.9+)
merged = dict1 | dict2 # new dict
dict1 |= dict2 # in-place mergeComprehensions
Comprehensions are concise, readable ways to build collections from iterables.
List Comprehension
squares = [x**2 for x in range(10)]
evens = [x for x in range(20) if x % 2 == 0]Dict Comprehension
word_lengths = {word: len(word) for word in ["apple", "fig", "banana"]}
# {"apple": 5, "fig": 3, "banana": 6}Set Comprehension
unique_lengths = {len(word) for word in ["cat", "dog", "fish", "ant"]}
# {3, 4}Generator Expressions
Replace square brackets with parentheses to get a generator — it yields items one at a time without building the entire list in memory:
total = sum(x**2 for x in range(1_000_000)) # memory-efficientNested Comprehensions
# Flatten a 2-D list
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flat = [num for row in matrix for num in row]
# [1, 2, 3, 4, 5, 6, 7, 8, 9]
# Transpose
transposed = [[row[i] for row in matrix] for i in range(3)]Readability tip: If a comprehension spans more than two lines or has complex logic, a regular
forloop is usually clearer.
Code Examples
inventory = {"apple": 50, "banana": 30, "cherry": 20}
# get() with default avoids KeyError
print(inventory.get("apple")) # exists
print(inventory.get("mango", 0)) # missing — returns 0
# update() merges another dict
inventory.update({"banana": 45, "date": 10})
print("After update:", inventory)
# Iterate over items
print("\nInventory list:")
for item, qty in inventory.items():
print(f" {item}: {qty} units")
# pop removes and returns
removed_qty = inventory.pop("cherry")
print(f"\nRemoved cherry (had {removed_qty})")
print("Keys:", list(inventory.keys()))get() is safer than direct key access because it returns a default value instead of raising KeyError. update() is great for merging configuration dictionaries. Iterating with .items() gives both key and value simultaneously.
# List comprehension
squares = [x**2 for x in range(1, 8)]
print("Squares:", squares)
# Filtered list comprehension
evens = [x for x in range(20) if x % 2 == 0]
print("Evens:", evens)
# Dict comprehension — map word to its length
words = ["python", "is", "awesome"]
lengths = {w: len(w) for w in words}
print("Lengths:", lengths)
# Invert a dictionary
original = {"a": 1, "b": 2, "c": 3}
inverted = {v: k for k, v in original.items()}
print("Inverted:", inverted)
# Set comprehension — unique first letters
names = ["Alice", "Bob", "Anna", "Charlie", "Brian"]
initials = {name[0] for name in names}
print("Initials:", sorted(initials))Comprehensions are more Pythonic and often faster than equivalent for-loop constructions because they are optimized at the bytecode level. Dict comprehensions are perfect for transforming or inverting mappings.
# Generator expression — memory-efficient
numbers = range(1, 11)
total = sum(x**2 for x in numbers)
print("Sum of squares 1-10:", total)
# Nested list comprehension — flatten 2-D matrix
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flat = [num for row in matrix for num in row]
print("Flattened:", flat)
# Nested comprehension — multiplication table
table = [[i * j for j in range(1, 6)] for i in range(1, 6)]
print("5x5 Multiplication table:")
for row in table:
print(row)Generator expressions use parentheses instead of brackets. They are lazy — they produce values on demand — making them ideal for large datasets. Nested comprehensions read left-to-right; the outer loop comes first.
Quick Quiz
1. What does dict.get('key', 'default') return when 'key' is not in the dictionary?
2. Which of the following is a set comprehension?
3. What is the main advantage of a generator expression over a list comprehension?
Was this lesson helpful?