Teacher's Guide
Chapter 8: Using Dictionaries
Teaching Objectives
By the end of this chapter, students should:
- Understand what dictionaries are and how they differ from lists
- Know how to create and manipulate dictionaries in Python
- Master accessing, adding, modifying, and deleting dictionary elements
- Learn common dictionary methods and operations
- Apply dictionaries to solve real-world problems
Preparation
Before teaching this chapter, ensure:
- Students understand basic Python data types and operators
- Students are comfortable with lists and basic data structures
- Your teaching environment allows for interactive coding demonstrations
- You have prepared simple examples of dictionary usage
Lesson Overview
1. Introduction to Dictionaries (15 minutes)
Start by explaining what dictionaries are:
- Dictionaries are collections of key-value pairs
- Each key maps to a value (like a real dictionary maps words to definitions)
- Keys must be unique and immutable (typically strings, numbers, or tuples)
- Values can be any data type (strings, numbers, lists, other dictionaries, etc.)
- Dictionaries are unordered in Python versions before 3.7 (ordered from 3.7 onward)
Basic dictionary creation:
# Creating a simple dictionary
student = {
"name": "Alice",
"age": 15,
"grade": 9,
"subjects": ["Math", "Science", "English"]
}
# Display the dictionary
print(student)
Alternative creation methods:
# Using dict() constructor
person = dict(name="Bob", age=25, city="New York")
print(person)
# Creating an empty dictionary and adding items
pet = {}
pet["type"] = "Dog"
pet["name"] = "Buddy"
pet["age"] = 3
print(pet)
Teaching points:
- Dictionary keys are written inside curly braces
{} - Each key is followed by a colon
:and then its value - Key-value pairs are separated by commas
- We can create dictionaries using different methods
- Dictionaries are mutable (can be changed)
2. Accessing Dictionary Elements (20 minutes)
Explain how to retrieve values from dictionaries:
# Accessing values using keys
student = {
"name": "Alice",
"age": 15,
"grade": 9,
"subjects": ["Math", "Science", "English"]
}
print(f"Name: {student['name']}")
print(f"Age: {student['age']}")
print(f"Subjects: {student['subjects']}")
# Accessing list items within dictionaries
print(f"First subject: {student['subjects'][0]}")
Using get() method:
# Using get() method (safer way to access values)
name = student.get("name")
print(f"Name: {name}")
# Providing default value with get()
hobby = student.get("hobby", "No hobby listed")
print(f"Hobby: {hobby}") # Uses default value
# This would cause an error:
# print(student["hobby"]) # KeyError
Checking if a key exists:
# Check if key exists in dictionary
if "age" in student:
print(f"The student is {student['age']} years old")
if "address" not in student:
print("No address provided")
Teaching points:
- Access values by using square brackets
[]with the key - The
get()method provides a safer way to access values - Use
get(key, default)to provide a default value if the key doesn't exist - Use
inandnot inoperators to check if a key exists - Accessing a non-existent key with square brackets causes a KeyError
3. Modifying Dictionaries (15 minutes)
Show how to modify dictionary contents:
# Modifying a dictionary
student = {
"name": "Alice",
"age": 15,
"grade": 9
}
# Changing values
student["age"] = 16
print(f"Updated age: {student['age']}")
# Adding new key-value pairs
student["school"] = "Lincoln High"
print(f"Added school: {student['school']}")
# Adding a list as a value
student["subjects"] = ["Math", "Science", "History"]
print(f"Added subjects: {student['subjects']}")
# Modify a list value
student["subjects"].append("Art")
print(f"Updated subjects: {student['subjects']}")
# Removing a key-value pair
del student["grade"]
print("After removing grade:", student)
# Alternative way to remove (and get the value)
school = student.pop("school")
print(f"Removed school: {school}")
print("After pop:", student)
Teaching points:
- Assign a new value to an existing key to update it
- Add a new key-value pair by simply assigning a value to a new key
- Remove keys using
delorpop() pop()returns the value being removed- Dictionary values can be complex data types like lists
4. Dictionary Methods (20 minutes)
Introduce useful dictionary methods:
# Create a sample dictionary
book = {
"title": "Harry Potter",
"author": "J.K. Rowling",
"year": 1997,
"pages": 223
}
# Get all keys
keys = book.keys()
print("All keys:", keys)
print("Keys list:", list(keys))
# Get all values
values = book.values()
print("All values:", values)
print("Values list:", list(values))
# Get all key-value pairs as tuples
items = book.items()
print("All items:", items)
print("Items list:", list(items))
# Clear a dictionary
book_copy = book.copy() # Make a copy first
book_copy.clear()
print("Cleared dictionary:", book_copy)
# Update with another dictionary
book.update({"publisher": "Bloomsbury", "pages": 230})
print("After update:", book)
# setdefault - set a key if it doesn't exist
current_author = book.setdefault("author", "Unknown")
new_genre = book.setdefault("genre", "Fantasy")
print(f"Current author: {current_author}")
print(f"New genre: {new_genre}")
print("After setdefault:", book)
Teaching points:
keys(),values(), anditems()return special "view" objects- These views reflect changes to the dictionary
- Convert them to lists if needed
copy()creates a shallow copy of a dictionaryclear()removes all itemsupdate()adds or updates multiple key-value pairssetdefault()adds a key with a default value if the key doesn't exist
5. Dictionary Loops (15 minutes)
Demonstrate how to iterate through dictionaries:
# Sample dictionary
student = {
"name": "Alice",
"age": 16,
"grade": 10,
"subjects": ["Math", "Science", "English", "History"]
}
# Looping through keys
print("Keys in the dictionary:")
for key in student:
print(key)
# Alternative way to loop through keys
print("\nKeys (alternative method):")
for key in student.keys():
print(key)
# Looping through values
print("\nValues in the dictionary:")
for value in student.values():
print(value)
# Looping through key-value pairs
print("\nKey-value pairs:")
for key, value in student.items():
print(f"{key}: {value}")
# Accessing both keys and values
print("\nAnother way to access both:")
for key in student:
print(f"{key}: {student[key]}")
Teaching points:
- By default, iterating a dictionary gives its keys
- Use
values()to iterate through values - Use
items()to get key-value pairs as tuples - Unpacking tuples with
key, valuesyntax is convenient - Dictionaries are efficient for lookups and storing related data
6. Nested Dictionaries (20 minutes)
Explain how to work with nested dictionaries:
# Nested dictionary
school = {
"students": {
"Alice": {
"grade": 10,
"subjects": ["Math", "Science", "English"]
},
"Bob": {
"grade": 9,
"subjects": ["History", "Art", "Math"]
}
},
"teachers": {
"Mr. Smith": {
"subject": "Math",
"room": 101
},
"Ms. Johnson": {
"subject": "Science",
"room": 102
}
}
}
# Accessing nested values
print(f"Alice's grade: {school['students']['Alice']['grade']}")
print(f"Bob's subjects: {school['students']['Bob']['subjects']}")
print(f"Ms. Johnson's room: {school['teachers']['Ms. Johnson']['room']}")
# Modifying nested values
school['students']['Alice']['grade'] = 11
print(f"Alice's updated grade: {school['students']['Alice']['grade']}")
# Adding a new student
school['students']['Charlie'] = {
"grade": 10,
"subjects": ["Physics", "Computer Science"]
}
# Looping through nested dictionaries
print("\nAll students:")
for student_name, student_info in school['students'].items():
print(f"\n{student_name}:")
print(f" Grade: {student_info['grade']}")
print(f" Subjects: {', '.join(student_info['subjects'])}")
Teaching points:
- Dictionaries can contain other dictionaries as values
- Nested dictionaries allow for hierarchical data organization
- Access nested values by chaining multiple keys in square brackets
- Traversing deep nested structures requires careful organization
- Nested dictionaries are useful for complex data representation
7. Dictionary Comprehensions (15 minutes)
Introduce dictionary comprehensions:
# Creating dictionaries with comprehensions
# Basic example: squares of numbers
squares = {x: x**2 for x in range(1, 6)}
print("Squares:", squares)
# Creating from two lists
fruits = ["apple", "banana", "cherry"]
prices = [1.2, 0.9, 2.5]
fruit_prices = {fruit: price for fruit, price in zip(fruits, prices)}
print("Fruit prices:", fruit_prices)
# Conditional dictionary comprehension
even_squares = {x: x**2 for x in range(10) if x % 2 == 0}
print("Even squares:", even_squares)
# Transforming an existing dictionary
fruit_inventory = {"apple": 10, "banana": 15, "cherry": 8}
fruit_status = {
fruit: ("low" if count < 10 else "good")
for fruit, count in fruit_inventory.items()
}
print("Fruit status:", fruit_status)
Teaching points:
- Dictionary comprehensions provide a concise way to create dictionaries
- The syntax is
{key_expr: value_expr for item in iterable} - We can add conditions with
ifstatements - For generating keys and values from two sequences,
zip()is useful - Comprehensions can transform data from one form to another
8. Practical Applications (20 minutes)
Show real-world applications of dictionaries:
Counting word frequency:
# Count word frequency in a text
text = "the quick brown fox jumps over the lazy dog the fox was quick"
words = text.lower().split()
word_count = {}
for word in words:
if word in word_count:
word_count[word] += 1
else:
word_count[word] = 1
print("Word frequency:")
for word, count in word_count.items():
print(f"{word}: {count}")
# Alternative approach using get()
word_count2 = {}
for word in words:
word_count2[word] = word_count2.get(word, 0) + 1
print("\nUsing get() method:")
for word, count in sorted(word_count2.items()):
print(f"{word}: {count}")
Simple contact manager:
# Simple contact manager
contacts = {}
def add_contact(name, phone, email=None):
contacts[name] = {"phone": phone, "email": email}
print(f"Added contact: {name}")
def display_contacts():
if not contacts:
print("No contacts found.")
return
print("\nContacts List:")
print("-" * 40)
for name, info in contacts.items():
email_display = info["email"] if info["email"] else "N/A"
print(f"Name: {name}")
print(f"Phone: {info['phone']}")
print(f"Email: {email_display}")
print("-" * 40)
def find_contact(name):
contact = contacts.get(name)
if contact:
print(f"\nFound contact: {name}")
print(f"Phone: {contact['phone']}")
if contact['email']:
print(f"Email: {contact['email']}")
else:
print(f"\nNo contact found with name: {name}")
# Test the contact manager
add_contact("Alice", "555-1234", "[email protected]")
add_contact("Bob", "555-5678")
add_contact("Charlie", "555-9012", "[email protected]")
display_contacts()
find_contact("Bob")
find_contact("David")
Teaching points:
- Dictionaries are ideal for counting and categorizing items
- They're useful for representing complex real-world data
- Applications include contact lists, inventory systems, game state tracking
- Dictionaries allow for efficient lookups by key
9. Guided Practice (20 minutes)
Have students create these programs:
-
Student grades tracker:
# Create a program to track student grades # Initialize an empty dictionary to store student grades student_grades = {} # Function to add a new student def add_student(name): if name in student_grades: print(f"{name} is already in the system.") else: student_grades[name] = {} print(f"Added {name} to the system.") # Function to add a grade for a subject def add_grade(name, subject, grade): if name not in student_grades: print(f"Error: {name} not found.") return student_grades[name][subject] = grade print(f"Added {grade} for {name} in {subject}.") # Function to calculate average grade for a student def calculate_average(name): if name not in student_grades: print(f"Error: {name} not found.") return None grades = student_grades[name].values() if not grades: print(f"{name} has no grades yet.") return None average = sum(grades) / len(grades) return average # Function to display a student's grades def display_student(name): if name not in student_grades: print(f"Error: {name} not found.") return print(f"\nGrades for {name}:") if not student_grades[name]: print("No grades recorded yet.") return for subject, grade in student_grades[name].items(): print(f"{subject}: {grade}") average = calculate_average(name) if average is not None: print(f"Average: {average:.2f}") # Test the program add_student("Alice") add_student("Bob") add_grade("Alice", "Math", 95) add_grade("Alice", "Science", 88) add_grade("Alice", "English", 92) add_grade("Bob", "Math", 85) add_grade("Bob", "Science", 90) display_student("Alice") display_student("Bob") -
Simple inventory system:
# Create a simple inventory management system # Initialize inventory inventory = { "apple": {"price": 1.0, "quantity": 10}, "banana": {"price": 0.5, "quantity": 20}, "orange": {"price": 1.2, "quantity": 15} } # Function to display inventory def display_inventory(): print("\nCurrent Inventory:") print("-" * 50) print(f"{'Item':<10}{'Price':>10}{'Quantity':>15}{'Value':>15}") print("-" * 50) total_value = 0 for item, info in inventory.items(): value = info["price"] * info["quantity"] total_value += value print(f"{item:<10}${info['price']:>9.2f}{info['quantity']:>15}${value:>14.2f}") print("-" * 50) print(f"{'Total Value:':<35}${total_value:>14.2f}") # Function to add or update an item def update_item(item, price, quantity): if item in inventory: inventory[item]["price"] = price inventory[item]["quantity"] = quantity print(f"Updated {item} in inventory.") else: inventory[item] = {"price": price, "quantity": quantity} print(f"Added {item} to inventory.") # Function to remove an item def remove_item(item): if item in inventory: del inventory[item] print(f"Removed {item} from inventory.") else: print(f"Error: {item} not in inventory.") # Function to check if an item is in stock def check_stock(item, quantity=1): if item not in inventory: return False return inventory[item]["quantity"] >= quantity # Test the inventory system display_inventory() update_item("apple", 1.2, 15) # Update existing item update_item("grape", 2.0, 8) # Add new item remove_item("orange") print(f"\nApples in stock for 10 units: {check_stock('apple', 10)}") print(f"Bananas in stock for 25 units: {check_stock('banana', 25)}") display_inventory()
10. Challenge Activities (15 minutes)
For more advanced students:
-
Menu-based dictionary manipulation:
# Create a menu-based program to manipulate a dictionary def show_menu(): print("\nDictionary Operations") print("---------------------") print("1. Add/Update an entry") print("2. Delete an entry") print("3. Find an entry") print("4. Display all entries") print("5. Clear all entries") print("6. Exit") return input("Enter your choice (1-6): ") # Initialize an empty dictionary data = {} # Main program loop while True: choice = show_menu() if choice == "1": key = input("Enter key: ") value = input("Enter value: ") data[key] = value print(f"Added/Updated: {key} -> {value}") elif choice == "2": key = input("Enter key to delete: ") if key in data: del data[key] print(f"Deleted: {key}") else: print(f"Error: {key} not found") elif choice == "3": key = input("Enter key to find: ") if key in data: print(f"Found: {key} -> {data[key]}") else: print(f"Error: {key} not found") elif choice == "4": if not data: print("Dictionary is empty") else: print("\nCurrent Entries:") for key, value in data.items(): print(f"{key}: {value}") elif choice == "5": confirm = input("Are you sure you want to clear all entries? (y/n): ") if confirm.lower() == 'y': data.clear() print("Dictionary cleared") elif choice == "6": print("Exiting program...") break else: print("Invalid choice. Please enter a number from 1 to 6.") -
Morse code translator:
# Create a Morse code translator using dictionaries # Morse code dictionary morse_code = { 'A': '.-', 'B': '-...', 'C': '-.-.', 'D': '-..', 'E': '.', 'F': '..-.', 'G': '--.', 'H': '....', 'I': '..', 'J': '.---', 'K': '-.-', 'L': '.-..', 'M': '--', 'N': '-.', 'O': '---', 'P': '.--.', 'Q': '--.-', 'R': '.-.', 'S': '...', 'T': '-', 'U': '..-', 'V': '...-', 'W': '.--', 'X': '-..-', 'Y': '-.--', 'Z': '--..', '0': '-----', '1': '.----', '2': '..---', '3': '...--', '4': '....-', '5': '.....', '6': '-....', '7': '--...', '8': '---..', '9': '----.', '.': '.-.-.-', ',': '--..--', '?': '..--..', "'": '.----.', '!': '-.-.--', '/': '-..-.', '(': '-.--.', ')': '-.--.-', '&': '.-...', ':': '---...', ';': '-.-.-.', '=': '-...-', '+': '.-.-.', '-': '-....-', '_': '..--.-', '"': '.-..-.', '$': '...-..-', '@': '.--.-.' } # Create reverse lookup dictionary morse_to_char = {value: key for key, value in morse_code.items()} def text_to_morse(text): """Convert text to Morse code""" result = [] for char in text.upper(): if char == ' ': # Add space between words (conventionally 7 units) result.append(' ') elif char in morse_code: # Add the morse code and a space between characters result.append(morse_code[char] + ' ') else: # Handle unknown characters result.append('? ') return ''.join(result) def morse_to_text(morse): """Convert Morse code to text""" # Split by spaces (conventionally 3 spaces between words) words = morse.strip().split(' ') result = [] for word in words: # Split into characters (1 space between morse characters) chars = word.split() word_result = [] for char in chars: if char in morse_to_char: word_result.append(morse_to_char[char]) else: word_result.append('?') result.append(''.join(word_result)) return ' '.join(result) # Test the translator message = "Hello World" morse = text_to_morse(message) print(f"Original: {message}") print(f"Morse: {morse}") print(f"Decoded: {morse_to_text(morse)}") # Try with custom input custom_message = input("\nEnter a message to convert to Morse code: ") custom_morse = text_to_morse(custom_message) print(f"Morse: {custom_morse}") print(f"Decoded: {morse_to_text(custom_morse)}")
11. Review and Discussion (10 minutes)
- Review the key concepts covered
- Ask students to explain in their own words:
- What is a dictionary and when would you use one?
- How do dictionaries differ from lists?
- What are some common dictionary methods?
- How do you iterate through a dictionary?
Common Challenges and Solutions
- Understanding the key-value concept: Compare to real-world examples like a phonebook (name→number) or a dictionary (word→definition).
- Forgetting that dictionary keys must be immutable: Remind students that lists and dictionaries can't be used as keys.
- Confusion about dictionary order: Explain the historical unordered nature and the change in Python 3.7+.
- KeyError when accessing non-existent keys: Encourage using
get()or checking withinfirst.
Extension Activities
For students who finish early:
- Have them create a more complex dictionary-based application (e.g., a recipe manager)
- Challenge them to solve a data organization problem using nested dictionaries
- Ask them to convert between different data representations using dictionaries
Assessment
Look for these indicators of understanding:
- Students can create and manipulate dictionaries correctly
- They can choose appropriate techniques for different dictionary operations
- They understand common patterns like counting and grouping using dictionaries
- They can design solutions using dictionaries for complex data