Lesson 2
Mastering Python Dictionaries for Data Mapping
Introduction

Welcome to our Python data structures revision! Today, we will delve deeply into Python Dictionaries. Much like a bookshelf, dictionaries allow you to quickly select the book (value) you desire by reading its label (key). They are vital to Python for quickly accessing values using keys, as well as efficient key insertion and deletion. So, let's explore Python dictionaries for a clearer understanding of these concepts.

Python Dictionaries

Our journey starts with Python dictionaries, a pivotal data structure that holds data as key-value pairs. Imagine storing your friend's contact info in such a way that allows you to search for your friend's name (the key) and instantly find their phone number (the value).

Python
1class PhoneBook: 2 3 def __init__(self): 4 # An empty dictionary 5 self.contacts = {} 6 7 def add_contact(self, name, phone_number): 8 # Method to add a contact 9 self.contacts[name] = phone_number 10 11 def get_phone_number(self, name): 12 # Method to retrieve contact's phone number, or None, if it's in contacts 13 return self.contacts.get(name, None) 14 15# Create a PhoneBook instance 16phone_book = PhoneBook() 17 18# Add contacts 19phone_book.add_contact("Alice", "123-456-7890") 20phone_book.add_contact("Bob", "234-567-8901") 21print(phone_book.get_phone_number("Alice")) # Output: "123-456-7890" 22print(phone_book.get_phone_number("Bobby")) # Output: None

In the above code, we create a PhoneBook class that uses a dictionary to store contacts. As you can see, dictionaries simplify the processes of adding, modifying, and accessing information with unique keys.

Operations in Dictionaries

Python dictionaries enable a variety of operations for manipulating data, such as setting, getting, and deleting key-value pairs. Understanding these operations is crucial for efficient data handling in Python.

To add or update entries in a dictionary, you directly assign a value to a key. If the key exists, the value is updated; if not, a new key-value pair is added. This flexibility allows for dynamic updates and additions to the dictionary without needing a predefined structure.

The get operation is used to retrieve the value associated with a specific key. It provides a safe way to access values since it allows specifying a default value if the key does not exist, preventing errors that would arise from attempting to access a non-existent key.

Deleting an entry is done using the del statement followed by the key. This operation removes the specified key-value pair from the dictionary, which is essential for managing the contents of the dictionary actively.

Let’s see how these operations work in the context of a Task Manager class:

Python
1class TaskManager: 2 3 def __init__(self): 4 # Initialize with an empty dictionary 5 self.tasks = {} 6 7 def add_update_task(self, task_name, status): 8 # Add a new task or update an existing task 9 self.tasks[task_name] = status 10 11 def get_task_status(self, task_name): 12 # Retrieve the status of a task; Returns "Not Found" if the task does not exist 13 return self.tasks.get(task_name, "Not Found") 14 15 def delete_task(self, task_name): 16 # Removes a task using its name 17 if task_name in self.tasks: 18 del self.tasks[task_name] 19 else: 20 print(f"Task '{task_name}' not found.") 21 22# Test the TaskManager class 23my_tasks = TaskManager() 24my_tasks.add_update_task("Buy Milk", "Pending") 25print(my_tasks.get_task_status("Buy Milk")) # Output: Pending 26my_tasks.add_update_task("Buy Milk", "Completed") 27print(my_tasks.get_task_status("Buy Milk")) # Output: Completed 28 29my_tasks.delete_task("Buy Milk") 30print(my_tasks.get_task_status("Buy Milk")) # Output: Not Found

This example showcases how to leverage dictionary operations in Python to effectively manage data by adding, updating, retrieving, and deleting entries through a simulated Task Manager application.

Looping Through Dictionaries

Python provides an elegant way to loop through dictionaries by using a for loop. We can iterate through keys, values, or both simultaneously.

Let's explore this in our Task Manager example:

Python
1class TaskManager: 2 def __init__(self): 3 self.tasks = {} 4 5 def add_task(self, task_name, status): 6 self.tasks[task_name] = status 7 8 def print_all_tasks(self): 9 # Prints all tasks' keys 10 for task_name in self.tasks.keys(): 11 print(task_name) 12 13my_tasks = TaskManager() 14my_tasks.add_task("Buy Milk", "Pending") 15my_tasks.add_task("Pay Bills", "Completed") 16 17my_tasks.print_all_tasks()

In this case, the .keys() method provides all keys in our dictionary, enabling us to print all tasks in our task manager. You can also use .values() to get all values in the dictionary and .items() to get all items - tuples of (key, value) pairs.

Since Python 3.6, dictionaries keep the order of the insertion, and when looping, they are returned in the order of addition.

Nesting with Dictionaries

Nesting in dictionaries involves storing dictionaries within another dictionary. It's useful when associating multiple pieces of information with a key. Let's see how this works in a Student Database example. Here, we are using the .items() method that we mentioned before - it iterates through dictionary tuples of keys and values.

Python
1class StudentDatabase: 2 def __init__(self): 3 self.students = {} 4 5 def add_student(self, name, subjects): 6 # Adds students and subjects 7 self.students[name] = subjects 8 9 def get_mark(self, name, subject): 10 return self.students.get(name, {}).get(subject, "N/A") 11 12 def print_database(self): 13        # Prints student and their subjects with grades 14        for name, subjects in self.students.items(): 15            print("Student:", name) 16            for subject, grade in subjects.items(): 17                print(f"   Subject: {subject}, Grade: {grade}") 18 19# Create a StudentDatabase instance 20student_db = StudentDatabase() 21student_db.add_student("Alice", {"Math": "A", "English": "B"}) 22 23print(student_db.get_mark("Alice", "English")) # Output: "B" 24print(student_db.get_mark("Alice", "History")) # Output: "N/A" 25student_db.print_database() 26""" 27Output: 28Student: Alice 29 Subject: Math, Grade: A 30 Subject: English, Grade: B 31"""
Hands-on Example

Let's shift our focus to a more interactive and familiar scenario: managing a shopping cart in an online store. This hands-on example will demonstrate how dictionaries can be used to map product names to their quantities in a shopping cart. You will learn how to add products, update quantities, and retrieve the total number of items in the cart without the need for an external file.

Here’s how you can implement and manipulate a shopping cart using a Python dictionary:

Python
1class ShoppingCart: 2 3 def __init__(self): 4 # Initialize cart as an empty dictionary 5 self.cart = {} 6 7 def add_product(self, product_name, quantity): 8 """Add or update the quantity of a product in the cart.""" 9 if product_name in self.cart: 10 self.cart[product_name] += quantity 11 else: 12 self.cart[product_name] = quantity 13 14 def remove_product(self, product_name): 15 """Remove a product from the cart.""" 16 if product_name in self.cart: 17 del self.cart[product_name] 18 else: 19 print(f"{product_name} not found in your cart.") 20 21 def show_cart(self): 22 """Display the products and their quantities in the cart.""" 23 if not self.cart: 24 print("Your shopping cart is empty.") 25 else: 26 for product, quantity in self.cart.items(): 27 print(f"{product}: {quantity}") 28 29# Create an instance of ShoppingCart 30my_cart = ShoppingCart() 31 32# Add products and update their quantities 33my_cart.add_product("Apples", 5) 34my_cart.add_product("Bananas", 2) 35my_cart.add_product("Apples", 3) # Updates quantity of apples to 8 36 37# Display cart 38my_cart.show_cart() 39# Output: 40# Apples: 8 41# Bananas: 2 42 43# Remove a product and show the updated cart 44my_cart.remove_product("Bananas") 45my_cart.show_cart() 46# Output: 47# Apples: 8

This example showcases the practical application of dictionaries to manage a dynamic dataset, such as an online shopping cart. By using product names as keys and their quantities as values, we achieve efficient and flexible data manipulation. This exercise provides a solid foundation for understanding how to handle complex data structures in real-world Python applications.

Lesson Summary and Practice

Well done! Today, we delved into Python dictionaries and explored various operations on dictionaries. We now invite you to get hands-on experience with the upcoming practice exercises. To master these concepts and hone your Python dictionary skills, practice is key. Happy learning!

Enjoy this lesson? Now it's time to practice with Cosmo!
Practice is how you turn knowledge into actual skills.