Chapter 8: Dictionaries: Key-Value Pairs ๐
In the last chapter, you learned about lists โ collections where you access items by their position (index 0, 1, 2โฆ). But what if you want to organize data using meaningful labels instead of numbers? What if you want to store a personโs name, age, and email together in a way that makes sense?
Thatโs where dictionaries come in! They let you store data using descriptive keys like "name" or "age" instead of remembering that index 0 is the name and index 1 is the age. This makes your code more readable and powerful.
Introduction to Dictionaries ๐ฏ
A dictionary is a collection of key-value pairs. Each key acts like a label that points to a value. Think of it like a real dictionary where you look up a word (the key) to find its definition (the value).
Creating Dictionaries
To create a dictionary, use curly braces {} with key-value pairs separated by colons:
# A simple dictionary
student = {
"name": "Jordan",
"age": 14,
"grade": "9th"
}
Each entry has:
- A key (like
"name","age","grade") - A colon
: - A value (like
"Jordan",14,"9th") - A comma separating each pair (except the last one)
Keys are usually strings, but values can be any data type โ strings, numbers, booleans, lists, or even other dictionaries!
More Examples
# Game character stats
character = {
"name": "DragonSlayer",
"health": 100,
"mana": 50,
"level": 12,
"equipped": True
}
# Product information
product = {
"name": "Gaming Mouse",
"price": 49.99,
"in_stock": True,
"quantity": 15
}
# Empty dictionary
empty_dict = {}
Why Use Dictionaries?
Compare these two approaches:
Using a list (confusing):
student = ["Jordan", 14, "9th", "Math"]
# Is index 0 the name or age? Hard to remember!
print(student[0]) # What does this represent?
Using a dictionary (clear):
student = {
"name": "Jordan",
"age": 14,
"grade": "9th",
"favorite_subject": "Math"
}
print(student["name"]) # Obviously the name!
Dictionaries make your code self-documenting and much easier to understand.
Displaying Dictionaries
You can print an entire dictionary:
player = {"name": "Alex", "score": 1250, "level": 5}
print(player)
# Shows: {'name': 'Alex', 'score': 1250, 'level': 5}
Accessing Dictionary Values ๐
Unlike lists where you use numeric indices, dictionaries use keys to access values. This makes your code much more readable.
Using Keys
To access a value, use square brackets with the key:
student = {
"name": "Jordan",
"age": 14,
"grade": "9th",
"gpa": 3.8
}
print(student["name"]) # Shows: Jordan
print(student["age"]) # Shows: 14
print(student["gpa"]) # Shows: 3.8
Keys Are Case-Sensitive
Make sure your key matches exactly:
player = {"name": "Alex", "score": 1250}
print(player["name"]) # Works!
print(player["Name"]) # ERROR: KeyError: 'Name'
"name" and "Name" are different keys.
Using .get() Method
If you try to access a key that doesnโt exist, Python raises a KeyError:
student = {"name": "Jordan", "age": 14}
print(student["email"]) # ERROR: KeyError: 'email'
The .get() method provides a safer alternative. It returns None if the key doesnโt exist (or a default value you specify):
student = {"name": "Jordan", "age": 14}
# Returns None if key doesn't exist
email = student.get("email")
print(email) # Shows: None
# Return a default value if key doesn't exist
email = student.get("email", "No email on file")
print(email) # Shows: No email on file
# Key exists - works normally
name = student.get("name")
print(name) # Shows: Jordan
This is especially useful when youโre not sure if a key exists.
Using Dictionary Values
Once you access a value, you can use it like any other variable:
product = {
"name": "Laptop",
"price": 999.99,
"tax_rate": 0.08
}
price = product["price"]
tax = price * product["tax_rate"]
total = price + tax
print(f"Product: {product['name']}")
print(f"Price: ${price:.2f}")
print(f"Tax: ${tax:.2f}")
print(f"Total: ${total:.2f}")
Checking if a Key Exists
Use the in operator to check if a key exists before accessing it:
student = {"name": "Jordan", "age": 14, "grade": "9th"}
if "email" in student:
print(student["email"])
else:
print("Email not found")
if "name" in student:
print(f"Student name: {student['name']}")
Adding and Updating Entries โ๏ธ
Dictionaries are mutable, meaning you can change them after creation. You can add new key-value pairs or update existing ones.
Adding New Entries
To add a new key-value pair, simply assign a value to a new key:
student = {
"name": "Jordan",
"age": 14
}
print(student) # Shows: {'name': 'Jordan', 'age': 14}
# Add new entries
student["grade"] = "9th"
student["gpa"] = 3.8
student["email"] = "jordan@example.com"
print(student)
# Shows: {'name': 'Jordan', 'age': 14, 'grade': '9th', 'gpa': 3.8, 'email': 'jordan@example.com'}
If the key already exists, it updates the value. If it doesnโt, it creates a new entry.
Updating Existing Entries
To update a value, assign a new value to an existing key:
player = {
"name": "DragonSlayer",
"health": 100,
"score": 1000
}
print(f"Initial score: {player['score']}")
# Take damage
player["health"] -= 25
print(f"Health after damage: {player['health']}")
# Earn points
player["score"] += 500
print(f"New score: {player['score']}")
Using .update() Method
The .update() method adds or updates multiple entries at once:
student = {
"name": "Jordan",
"age": 14
}
# Update multiple fields
student.update({
"age": 15, # Update existing
"grade": "10th", # Add new
"honor_roll": True # Add new
})
print(student)
This is convenient when you have several updates to make.
Practical Example: Character Stats
# Initialize character
character = {
"name": "Warrior",
"level": 1,
"health": 100,
"mana": 50,
"experience": 0
}
print("=== Character Created ===")
print(f"Name: {character['name']}")
print(f"Level: {character['level']}")
print()
# Character gains experience
print("Character completes a quest!")
character["experience"] += 150
# Level up when experience reaches 100
if character["experience"] >= 100:
character["level"] += 1
character["health"] += 20
character["mana"] += 10
print("๐ Level Up!")
print(f"Level: {character['level']}")
print(f"Health: {character['health']}")
print(f"Experience: {character['experience']}")
Removing Entries ๐๏ธ
Python provides several ways to remove entries from dictionaries.
Using del Statement
Remove a key-value pair by key:
student = {
"name": "Jordan",
"age": 14,
"temp_id": "TMP123",
"grade": "9th"
}
del student["temp_id"] # Remove the temporary ID
print(student)
# Shows: {'name': 'Jordan', 'age': 14, 'grade': '9th'}
Using .pop() Method
The .pop() method removes a key and returns its value:
inventory = {
"sword": 1,
"shield": 1,
"potion": 5
}
# Use a potion
potions_left = inventory.pop("potion")
print(f"Used 1 potion, {potions_left} total")
inventory["potion"] = potions_left - 1
print(inventory)
You can provide a default value if the key might not exist:
score = game_data.pop("bonus", 0) # Returns 0 if "bonus" doesn't exist
Using .clear() Method
Remove all entries but keep the dictionary:
cart = {"item1": "Book", "item2": "Pen", "item3": "Notebook"}
cart.clear()
print(cart) # Shows: {}
Looping Through Dictionaries ๐
Dictionaries are incredibly powerful when combined with loops. You can iterate over keys, values, or both.
Looping Over Keys
By default, looping over a dictionary gives you the keys:
grades = {
"Math": 90,
"Science": 85,
"English": 92,
"History": 88
}
for subject in grades:
print(subject)
Output:
Math
Science
English
History
You can also explicitly use .keys():
for subject in grades.keys():
print(subject)
Looping Over Values
To get just the values, use .values():
grades = {
"Math": 90,
"Science": 85,
"English": 92,
"History": 88
}
for grade in grades.values():
print(f"Grade: {grade}")
Output:
Grade: 90
Grade: 85
Grade: 92
Grade: 88
Looping Over Key-Value Pairs
To get both keys and values, use .items():
grades = {
"Math": 90,
"Science": 85,
"English": 92,
"History": 88
}
for subject, grade in grades.items():
print(f"{subject}: {grade}")
Output:
Math: 90
Science: 85
English: 92
History: 88
This is the most common and useful pattern.
Practical Examples
Example 1: Calculate total and average
prices = {
"laptop": 999.99,
"mouse": 24.99,
"keyboard": 79.99,
"monitor": 299.99
}
total = 0
for item, price in prices.items():
print(f"{item}: ${price:.2f}")
total += price
print(f"\nTotal: ${total:.2f}")
average = total / len(prices)
print(f"Average price: ${average:.2f}")
Example 2: Find highest value
scores = {
"Alice": 95,
"Bob": 87,
"Charlie": 92,
"Diana": 98
}
highest_name = ""
highest_score = 0
for name, score in scores.items():
if score > highest_score:
highest_score = score
highest_name = name
print(f"Highest score: {highest_name} with {highest_score}")
Example 3: Filter and display
inventory = {
"sword": 1,
"shield": 1,
"potion": 15,
"gold_coin": 250,
"mana_potion": 8
}
print("Items with quantity > 5:")
for item, quantity in inventory.items():
if quantity > 5:
print(f" {item}: {quantity}")
Example 4: Count and categorize
ages = {
"Alice": 12,
"Bob": 15,
"Charlie": 11,
"Diana": 14,
"Eve": 16
}
teens = 0
for name, age in ages.items():
if age >= 13:
print(f"{name} is a teenager ({age})")
teens += 1
print(f"\nTotal teenagers: {teens}")
Dictionary Helpers ๐ ๏ธ
Python provides several useful functions and methods for working with dictionaries.
The len() Function
Get the number of key-value pairs:
student = {
"name": "Jordan",
"age": 14,
"grade": "9th",
"gpa": 3.8
}
count = len(student)
print(f"The dictionary has {count} entries") # Shows: 4 entries
Getting All Keys or Values
Convert keys or values to lists:
grades = {"Math": 90, "Science": 85, "English": 92}
subjects = list(grades.keys())
scores = list(grades.values())
print(f"Subjects: {subjects}")
print(f"Scores: {scores}")
Copying Dictionaries
Create a copy with .copy():
original = {"name": "Alex", "score": 100}
backup = original.copy()
original["score"] = 200
print(f"Original: {original}") # Shows: {'name': 'Alex', 'score': 200}
print(f"Backup: {backup}") # Shows: {'name': 'Alex', 'score': 100}
Without .copy(), both variables would point to the same dictionary.
Merging Dictionaries
Combine two dictionaries:
defaults = {"theme": "dark", "language": "en", "notifications": True}
user_prefs = {"theme": "light", "font_size": 14}
# Python 3.9+: Use the | operator
settings = defaults | user_prefs
print(settings)
# Shows: {'theme': 'light', 'language': 'en', 'notifications': True, 'font_size': 14}
# Alternative: use .update()
all_settings = defaults.copy()
all_settings.update(user_prefs)
Checking for Keys
We already saw in, but here are more examples:
user = {"username": "alex123", "email": "alex@example.com"}
# Check if key exists
if "username" in user:
print(f"Username: {user['username']}")
# Check if key doesn't exist
if "phone" not in user:
print("No phone number on file")
Nested Dictionaries ๐๏ธ
Dictionaries can contain other dictionaries, allowing you to create complex data structures.
Basic Nesting
student = {
"name": "Jordan",
"age": 14,
"grades": {
"Math": 90,
"Science": 85,
"English": 92
},
"contact": {
"email": "jordan@example.com",
"phone": "555-0123"
}
}
# Access nested values
print(student["name"]) # Shows: Jordan
print(student["grades"]["Math"]) # Shows: 90
print(student["contact"]["email"]) # Shows: jordan@example.com
Multiple Entries
# Multiple students
students = {
"student1": {
"name": "Alice",
"grade": 90,
"year": "10th"
},
"student2": {
"name": "Bob",
"grade": 85,
"year": "9th"
},
"student3": {
"name": "Charlie",
"grade": 92,
"year": "10th"
}
}
# Loop through nested dictionaries
for student_id, info in students.items():
print(f"{student_id}:")
print(f" Name: {info['name']}")
print(f" Grade: {info['grade']}")
print(f" Year: {info['year']}")
print()
Quick Recap ๐ฏ
Youโve mastered dictionaries in Python:
- Create dictionaries with
{}and key-value pairs - Access values using keys in square brackets or
.get() - Add and update entries by assigning to keys
- Remove entries with
del,.pop(), or.clear() - Loop through keys, values, or items with
.items() - Use helpers like
len(),in,.keys(), and.values() - Nest dictionaries to create complex data structures
Dictionaries make organizing related data intuitive and efficient!
Hands-On Mini Project: Contact Book ๐
Letโs build a contact management system that uses dictionaries to store and organize contact information.
Your Mission
Create an interactive contact book where users can:
- Add new contacts
- View all contacts
- Search for a contact
- Update contact information
- Delete a contact
- Exit the program
Example Solution
print("=" * 60)
print(" CONTACT BOOK MANAGER")
print("=" * 60)
print()
# Initialize empty contact book
contacts = {}
# Main program loop
running = True
while running:
# Display menu
print("\nWhat would you like to do?")
print("1. Add a contact")
print("2. View all contacts")
print("3. Search for a contact")
print("4. Update a contact")
print("5. Delete a contact")
print("6. Exit")
choice = input("\nEnter your choice (1-6): ")
print()
# Add a contact
if choice == "1":
print("=== Add New Contact ===")
name = input("Enter name: ").strip()
if name in contacts:
print(f"โ {name} already exists!")
else:
phone = input("Enter phone number: ").strip()
email = input("Enter email: ").strip()
contacts[name] = {
"phone": phone,
"email": email
}
print(f"โ Added {name} to contacts!")
# View all contacts
elif choice == "2":
if len(contacts) == 0:
print("Your contact book is empty.")
else:
print("=" * 60)
print("ALL CONTACTS:")
print("=" * 60)
for name, info in contacts.items():
print(f"\n๐ {name}")
print(f" Phone: {info['phone']}")
print(f" Email: {info['email']}")
print("\n" + "=" * 60)
print(f"Total contacts: {len(contacts)}")
# Search for a contact
elif choice == "3":
search_name = input("Enter name to search: ").strip()
if search_name in contacts:
info = contacts[search_name]
print("\n" + "=" * 60)
print(f"๐ {search_name}")
print(f" Phone: {info['phone']}")
print(f" Email: {info['email']}")
print("=" * 60)
else:
print(f"โ {search_name} not found in contacts.")
# Update a contact
elif choice == "4":
update_name = input("Enter name to update: ").strip()
if update_name not in contacts:
print(f"โ {update_name} not found in contacts.")
else:
print(f"\nCurrent information for {update_name}:")
print(f"Phone: {contacts[update_name]['phone']}")
print(f"Email: {contacts[update_name]['email']}")
print()
print("Enter new information (press Enter to keep current):")
new_phone = input(f"Phone [{contacts[update_name]['phone']}]: ").strip()
new_email = input(f"Email [{contacts[update_name]['email']}]: ").strip()
# Update only if new value provided
if new_phone:
contacts[update_name]['phone'] = new_phone
if new_email:
contacts[update_name]['email'] = new_email
print(f"โ Updated {update_name}!")
# Delete a contact
elif choice == "5":
delete_name = input("Enter name to delete: ").strip()
if delete_name not in contacts:
print(f"โ {delete_name} not found in contacts.")
else:
confirm = input(f"Are you sure you want to delete {delete_name}? (yes/no): ")
if confirm.lower() == "yes":
contacts.pop(delete_name)
print(f"โ Deleted {delete_name} from contacts.")
else:
print("Cancelled.")
# Exit
elif choice == "6":
print(f"You have {len(contacts)} contact(s) in your book.")
print("\nThanks for using Contact Book Manager!")
print("Goodbye! ๐")
running = False
# Invalid choice
else:
print("โ Invalid choice. Please enter 1-6.")
print()
print("=" * 60)
Challenge Yourself
Enhance your contact book with these features:
- Multiple phone numbers โ Store home, work, and mobile numbers
- Address information โ Add street, city, state, zip
- Categories โ Tag contacts as family, friends, work, etc.
- Birthday tracking โ Store and display birthdays
- Favorites โ Mark certain contacts as favorites
- Export contacts โ Display all contacts in a formatted way to copy
- Advanced search โ Search by phone number or email, not just name
- Sort contacts โ Display contacts alphabetically
- Notes field โ Add custom notes to each contact
- Statistics โ Show how many contacts in each category
Tips for Building
- Use
.strip()on input to remove extra spaces - Check if a contact exists before trying to update or delete
- Validate input (e.g., ensure email contains @)
- Use nested dictionaries for complex contact information
- Give clear feedback after each operation
- Consider using
.get()for safer access to nested values
Whatโs Next?
In the next chapter, youโll learn about functions โ how to create your own reusable blocks of code! Youโll discover how to organize your programs better and avoid repeating yourself.
Get ready to write cleaner, more organized code!
Excellent work! Dictionaries are incredibly powerful for organizing real-world data!