Creating Dictionaries
A dictionary is created with curly braces {}. Each entry is a key: value pair separated by a colon, and pairs are separated by commas.
# Literal syntax (most common)
person = {
"name": "Alice",
"age": 30,
"city": "New York",
"is_student": False
}
# Empty dictionary
empty_dict = {}
# Using dict() constructor
car = dict(make="Toyota", model="Camry", year=2022)
# From a list of pairs
pairs = [("a", 1), ("b", 2), ("c", 3)]
from_pairs = dict(pairs)
print(person)
print(car)
print(from_pairs)
print(f"Number of keys: {len(person)}")
Dictionary keys must be immutable: strings, integers, floats, booleans, and tuples are valid keys. Lists and other dicts cannot be keys because they're mutable. String keys are by far the most common in real-world code.
Accessing Values
Access values using the key in square brackets. If the key doesn't exist, it raises a KeyError. Use the .get() method to safely access keys that may not exist.
product = {
"name": "Laptop",
"brand": "TechBrand",
"price": 999.99,
"in_stock": True
}
# Direct access (raises KeyError if missing)
print(product["name"]) # Laptop
print(product["price"]) # 999.99
# Safe access with .get() - returns None if missing
print(product.get("brand")) # TechBrand
print(product.get("color")) # None
print(product.get("color", "N/A")) # N/A (default value)
# Check if a key exists
if "in_stock" in product:
print("Stock info available")
# Check if key NOT in dict
if "discount" not in product:
print("No discount key")
Adding and Updating Keys
student = {"name": "Bob", "age": 20}
# Add a new key
student["grade"] = "A"
student["major"] = "Computer Science"
print(student)
# Update an existing key (overwrites the value)
student["age"] = 21
print("After update:", student)
# Update multiple keys at once with .update()
student.update({
"year": 2,
"gpa": 3.8,
"age": 22 # also updates existing key
})
print("After .update():", student)
Deleting Keys
config = {
"host": "localhost",
"port": 8080,
"debug": True,
"timeout": 30,
"retries": 3
}
# del - raises KeyError if key not found
del config["debug"]
print(config)
# .pop() - removes and returns the value; optional default
timeout = config.pop("timeout")
print(f"Removed timeout: {timeout}")
missing = config.pop("nonexistent", "default_val")
print(f"Pop missing key: {missing}")
# .popitem() - removes and returns the last inserted pair (Python 3.7+)
last_key, last_val = config.popitem()
print(f"Popped last item: {last_key} = {last_val}")
# .clear() - empties the dictionary
temp = {"a": 1, "b": 2}
temp.clear()
print("After clear:", temp)
Key Dictionary Methods
| Method | Description | Returns |
|---|---|---|
d.keys() | All keys | dict_keys view |
d.values() | All values | dict_values view |
d.items() | All key-value pairs as tuples | dict_items view |
d.get(k, default) | Value for key k, or default | value or default |
d.update(other) | Merge another dict into d | None |
d.pop(k, default) | Remove key k and return value | value or default |
d.popitem() | Remove and return last item | (key, value) tuple |
d.setdefault(k, default) | Return value; insert default if missing | value |
d.clear() | Remove all items | None |
d.copy() | Shallow copy | new dict |
Iterating Over Dictionaries
scores = {
"Alice": 95,
"Bob": 82,
"Carol": 91,
"David": 78
}
# Iterate keys (default)
print("Students:")
for name in scores:
print(f" {name}")
# Iterate values
print("\nScores:")
for score in scores.values():
print(f" {score}")
# Iterate key-value pairs (most common)
print("\nFull report:")
for name, score in scores.items():
grade = "Pass" if score >= 80 else "Fail"
print(f" {name:<8}: {score} ({grade})")
# Find the top scorer
top = max(scores, key=lambda name: scores[name])
print(f"\nTop scorer: {top} with {scores[top]}")
setdefault() β Powerful Grouping Pattern
setdefault(key, default) returns the value for a key if it exists, or inserts the key with the default value and returns it. This is perfect for building dictionaries of lists (grouping items).
# Group words by their first letter
words = ["apple", "avocado", "banana", "blueberry", "cherry", "apricot", "coconut"]
grouped = {}
for word in words:
letter = word[0]
grouped.setdefault(letter, []).append(word)
for letter, group in sorted(grouped.items()):
print(f" {letter}: {group}")
Nested Dictionaries
Dictionary values can themselves be dictionaries. This is used frequently to represent structured data like records, configurations, and API responses.
company = {
"name": "TechCorp",
"employees": {
"E001": {
"name": "Alice",
"role": "Engineer",
"salary": 95000
},
"E002": {
"name": "Bob",
"role": "Manager",
"salary": 110000
},
"E003": {
"name": "Carol",
"role": "Designer",
"salary": 85000
}
}
}
# Access nested values
print(company["name"])
print(company["employees"]["E001"]["name"]) # Alice
print(company["employees"]["E002"]["salary"]) # 110000
# Update a nested value
company["employees"]["E003"]["salary"] = 90000
# Add a new nested record
company["employees"]["E004"] = {
"name": "David",
"role": "DevOps",
"salary": 100000
}
# Iterate nested dict
print("\nAll employees:")
for emp_id, info in company["employees"].items():
print(f" {emp_id}: {info['name']} ({info['role']}) β ${info['salary']:,}")
Chaining bracket access on a nested dict raises KeyError if any level is missing. Use .get() at each level: d.get("a", {}).get("b", default). Or use the collections.defaultdict for auto-creating nested structures.
Dictionary Comprehensions
Like list comprehensions, dict comprehensions let you build dictionaries in a single line using the syntax {key: value for item in iterable}.
# Square each number as a key-value pair
squares = {n: n**2 for n in range(1, 6)}
print(squares) # {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
# Filter: only include even squares
even_squares = {n: n**2 for n in range(1, 11) if n % 2 == 0}
print(even_squares) # {2: 4, 4: 16, 6: 36, 8: 64, 10: 100}
# Invert a dictionary (swap keys and values)
original = {"a": 1, "b": 2, "c": 3}
inverted = {v: k for k, v in original.items()}
print(inverted) # {1: 'a', 2: 'b', 3: 'c'}
# Build a word-length mapping
words = ["python", "is", "awesome", "programming"]
word_lengths = {word: len(word) for word in words}
print(word_lengths)
Practical Real-World Example
def word_frequency(text):
"""Count how many times each word appears in a text."""
words = text.lower().split()
freq = {}
for word in words:
# Remove basic punctuation
word = word.strip(".,!?;:")
freq[word] = freq.get(word, 0) + 1
return freq
text = """Python is great. Python is easy to learn.
Python is used for data science and web development.
Learning Python is fun!"""
freq = word_frequency(text)
# Sort by frequency (most common first)
sorted_freq = dict(sorted(freq.items(), key=lambda item: item[1], reverse=True))
print("Word frequencies:")
for word, count in list(sorted_freq.items())[:8]:
bar = "β" * count
print(f" {word:<12}: {count} {bar}")
ποΈ Practical Exercise
- Create a dictionary representing a book (title, author, year, pages, genre). Print each field using a
forloop over.items(). - Write code that safely retrieves a key that might not exist, providing a meaningful default value using
.get(). - Given a list of numbers, use a dict comprehension to create a dictionary where each number is a key and its cube is the value.
- Write a function
count_chars(text)that returns a dictionary of character frequencies for letters only (ignore spaces and punctuation). - Create a nested dictionary of 3 cities, each with keys for population, country, and timezone. Write code to print a formatted summary of each city.
π₯ Challenge
Build a simple inventory management system using a dictionary. Each product name is a key; each value is a nested dict with price, quantity, and category. Implement functions: add_product(inventory, name, price, qty, category), sell(inventory, name, qty) (reduce quantity; warn if insufficient stock), restock(inventory, name, qty), and report(inventory) (print a table with total values per item and overall inventory value). Test all functions with sample data.
Interview Questions on Python Dictionaries
- What types can be used as dictionary keys? Why can't lists be keys?
- What is the difference between
dict[key]anddict.get(key)? - How do you merge two dictionaries? Describe two ways (including Python 3.9+ syntax).
- What does
dict.setdefault(key, default)do? Give a real-world use case. - What is the time complexity of a dictionary lookup in Python? Why is it so fast?
- How do you iterate over a dictionary's key-value pairs simultaneously?
- What is a dictionary comprehension? Write one that inverts a dictionary.
- How are Python dictionaries ordered? Was this always the case?
π Summary
- Dictionaries store key-value pairs in curly braces
{}. Keys must be immutable. - Access values with
dict[key](raisesKeyErrorif missing) ordict.get(key, default)(safe). - Add or update a key with assignment:
dict[key] = value. Use.update()to merge multiple pairs. - Delete with
del dict[key],dict.pop(key)(returns value), ordict.popitem()(returns last pair). .keys(),.values(), and.items()return live views of the dict's data..setdefault(key, default)is ideal for grouping patterns.- Nested dicts can represent complex structured data; chain bracket access carefully.
- Dict comprehensions
{k: v for ...}create dicts concisely from any iterable. - Since Python 3.7, dicts maintain insertion order.
Related Topics
Frequently Asked Questions
Since Python 3.7, dictionaries maintain insertion order as a language guarantee (it was an implementation detail in CPython 3.6). If you iterate a dict, items come out in the order they were added. For Python 3.6 and earlier you needed collections.OrderedDict for guaranteed ordering.
Several ways: (1) d1.update(d2) β modifies d1 in place. (2) {**d1, **d2} β creates a new merged dict (Python 3.5+). (3) d1 | d2 β new merged dict (Python 3.9+). (4) d1 |= d2 β merge d2 into d1 in place (Python 3.9+). In all cases, if both dicts share a key, the right-side value wins.
Dictionaries are implemented as hash tables. When you store a key, Python computes a hash of it (a fixed-size integer) and uses that hash to determine where to store the value. Retrieval computes the same hash and goes directly to that location β O(1) average time, independent of dictionary size. This is why dict keys must be hashable (immutable).
No. Dictionary keys are unique. If you write d = {"a": 1, "a": 2}, the second value silently overwrites the first, giving {"a": 2}. Python won't raise an error β so be careful when building dicts programmatically that you don't accidentally overwrite important data.
dict.keys() returns a view of all keys. dict.items() returns a view of all key-value pairs as 2-tuples. dict.values() returns just the values. These are view objects β they reflect the dict in real time, so if you modify the dict, the views update. Convert to list() if you need a snapshot.