Skip to Content
Course content

42: Iterating Over Dictionaries

Click on the "Edit" button in the top corner of the screen to edit your slide content.

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.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.