Python
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax and Data Types
-
Section 3: Collections
-
39: Set Operations: Union, Intersection, Difference
-
Section 4: Control Flow
-
Section 5: Functions
-
Section 6: Turtle Graphics and Early Practice Projects
-
Section 7: Working with Files and I/O
-
Section 8: Regular Expressions
-
Section 9: Object-Oriented Python
-
Section 10: Error Handling
-
Section 11: Modules and Packages
-
Section 12: Iterators, Generators, and Functional Tools
-
Section 13: Decorators and Metaprogramming
-
Section 14: Concurrency and Parallelism
-
Section 15: Working with Dates, Times, and Numbers
-
Section 16: Standard Library Deep Dive I: Data Structures
-
Section 17: Standard Library Deep Dive II: System and Introspection
-
Section 18: Standard Library Deep Dive III: Security and Encoding
-
Section 19: Standard Library Deep Dive IV: Text and Data Utilities
-
Section 20: Networking and Web Basics
-
Section 21: Working with Databases
-
Section 22: Testing and Quality
-
Section 23: Advanced Typing
-
Section 24: Context Managers and Resource Handling
-
Section 25: Text, Unicode, and Binary Data
-
Section 26: More Functional and Iteration Tools
-
Section 27: Data Validation and Configuration
-
Section 28: Working with Images and Media
-
Section 29: Property-Based and Documentation Testing
-
Section 30: Packaging and Deployment
-
Section 31: Performance and Internals
-
Section 32: Design Patterns in Python
-
Section 33: GUI Programming
-
Section 34: Security Basics
-
Section 35: Data Structures and Algorithms
-
Section 36: Practical Projects
-
Section 37: Capstone Projects
-
Section 38: Interview and Algorithm Practice
-
Section 39: Writing Idiomatic Python
42: Iterating Over Dictionaries
A few years ago, I was reviewing a pull request from a junior dev who was building a system to monitor server health. He had a dictionary where the keys were server hostnames and the values were their current status (like "Online" or "Critical"). He wanted to print a report of every server that was failing, but his code looked like this: for server in server_status: print(server). He was baffled why his report was just a list of names with no status attached. He thought the dictionary was "swallowing" his data, when in reality, he had just bumped into the default behavior of Python dictionary iteration.
Navigating Keys and Values
When you loop over a dictionary using a standard for loop, Python assumes you only care about the keys. It's a shorthand that keeps your code clean if that's all you need. However, most of the time, the real magic is in the values. If you only need the data and don't care which key it belongs to, you can use the .values() method.
inventory = {"apples": 15, "bananas": 22, "oranges": 8}
# This only gives us the names of the fruits
for fruit in inventory:
print(f"We have {fruit} in stock.")
# This only gives us the quantities
for count in inventory.values():
print(f"Quantity: {count}")
I usually find that using the default loop is fine for quick checks, but being explicit with .keys() can sometimes make your intent clearer to other developers reading your code.
Unpacking with .items()
In the server health example I mentioned earlier, the developer needed both the hostname and the status. This is where .items() becomes your best friend. This method returns the dictionary's entries as pairs (tuples), which you can "unpack" directly in the loop header. It's arguably the most common way I write dictionary loops in production code because it's readable and efficient.
server_status = {
"web-prod-01": "Online",
"db-prod-01": "Critical",
"cache-prod-01": "Online",
"web-prod-02": "Offline"
}
for server, status in server_status.items():
if status != "Online":
print(f"ALERT: {server} is currently {status}!")
Notice how we use two variables—server and status. Python takes the key and the value from each pair and assigns them respectively. It's much cleaner than looking up the value manually inside the loop using the key, which would require an extra dictionary hit every single time.
The Danger of Mid-Loop Mutations
Here is a warning I wish someone had given me earlier in my career: never add or remove items from a dictionary while you are iterating over it. If you try to del a key from the same dictionary you're currently looping through, Python will throw a RuntimeError: dictionary changed size during iteration. It's a safety mechanism to prevent the loop from skipping elements or crashing.
If you need to filter a dictionary—say, removing all servers that are "Online" to create a "Needs Attention" list—don't delete items in place. Instead, create a new dictionary using a comprehension or iterate over a list of the keys. By calling list(my_dict.keys()), you create a static snapshot of the keys, allowing you to modify the original dictionary without triggering that error.
📋 Practical Task
Build a Discount Application System
You have been handed a dictionary of customer accounts and their current loyalty point balances. Your task is to create a script that applies a "Points Bonus" to specific customers.
Requirements:
- Start with this dictionary:
customers = {"Alice": 450, "Bob": 120, "Charlie": 800, "Diana": 310} - Iterate through the dictionary using
.items(). - If a customer has fewer than 500 points, add a 100-point "Welcome Bonus" to their total.
- If they have 500 or more, add a 50-point "Loyalty Bonus".
- Print a final summary showing each customer's name and their updated balance.
- Constraint: Ensure you are updating the values within the existing dictionary.
There are no comments for now.