livepython.net
CHAPTER 13Dictionaries
13.4  LOOPING

Loop Through a Dictionary in Python

Loop Through the Keys of a Dictionary

A for loop over a dictionary goes through its keys, one at a time, in the order they were added. Inside the loop, d[key] gives you the value that goes with each key.

Think of it like a waiter reading the menu card from top to bottom: each dish name is a key, and the price next to it is the value.

PYTHONedit me
prices = {"tea": 15, "coffee": 25, "juice": 40}
for item in prices:
    print(item, "costs", prices[item])
OUTPUT
tea costs 15
coffee costs 25
juice costs 40

The rules

  • for key in d: gives you the keys, not the values and not the pairs.
  • The order is the order the keys were added, so the output is always the same.
  • Use d[key] inside the loop to get the value. The key is surely there, so no KeyError.
  • Name the loop variable after what the keys are: item, name, word.

keys() says the same thing

d.keys() gives the keys too. for item in prices.keys(): works exactly like for item in prices:. The short version is more common, but some people like how clearly keys() reads:

PYTHONedit me
ages = {"Sunny": 25, "Rocky": 30}
for name in ages.keys():
    print(name)
OUTPUT
Sunny
Rocky

Combine with if

An if inside the loop picks out some of the pairs, like the counting loops of chapter 10:

PYTHONedit me
prices = {"tea": 15, "coffee": 25, "juice": 40}
for item in prices:
    if prices[item] > 20:
        print(item)
OUTPUT
coffee
juice

Avoid: adding or removing keys while you loop

PYTHONedit me
ages = {"Sunny": 25, "Rocky": 30}
for name in ages:
    ages["Lucky"] = 22
OUTPUT
RuntimeError: dictionary changed size during iteration

Python stops the loop when the dictionary grows or shrinks under it. Changing the value of an existing key is fine. To remove keys, collect them in a list first, then remove them after the loop.

for key in d: goes through the keys in order; d[key] gives each value.

your turnPredict the output

What will this print?

pets = {"Rocky": "dog", "Lucky": "cat"} for p in pets: print(p)
Your turn! What will this code show on the screen?
your turnFill the gap

Print each name with its score

scores = {"Sunny": 8, "Rocky": 6} for name in scores: print(name, ?)

It should print: Sunny 8 Rocky 6

Which piece makes this code work?

Loop Over Dictionary Values with values()

The values() method gives you only the values of a dictionary, without the keys. Loop over it when the names don't matter, only the numbers or words stored under them.

Think of it like emptying your piggy bank onto the table: you count the coins, and you don't care which slot each one came from.

PYTHONedit me
bill = {"pizza": 250, "drinks": 90, "dessert": 120}
total = 0
for cost in bill.values():
    total += cost
print("Total:", total)
OUTPUT
Total: 460

That's the running total from chapter 10: start at 0 before the loop, add inside it, print after it.

sum(), min() and max() work too

You used these on lists in chapter 9. They also take values() directly:

PYTHONedit me
marks = {"Sunny": 82, "Rocky": 67, "Lucky": 91}
print(sum(marks.values()))
print(max(marks.values()))
print(min(marks.values()))
OUTPUT
240
91
67

The rules

  • d.values() gives the values in the same order as the keys.
  • The same value can appear more than once, unlike keys.
  • in with values() checks the values: 91 in marks.values() is True.
  • You can't get back to the key from a value. If you need the name too, use items(), the next lesson.
PYTHONedit me
marks = {"Sunny": 82, "Rocky": 67, "Lucky": 91}
print(91 in marks)
print(91 in marks.values())
OUTPUT
False
True

Avoid: sum() on the dictionary itself

sum(marks) tries to add up the keys, which are strings:

PYTHONedit me
marks = {"Sunny": 82, "Rocky": 67}
print(sum(marks))
OUTPUT
TypeError: unsupported operand type(s) for +: 'int' and 'str'

The message says Python tried to add a number and a string with +. Add .values() and it works.

Common beginner doubt: "What does print(marks.values()) show?" Something like dict_values([82, 67, 91]). It's a special view of the values, made for looping. Loop over it, or pass it to sum(), max() or min().

d.values() gives only the values: loop over it, or pass it to sum(), min() or max().

your turnType the output

Type what this prints

cart = {"pen": 10, "book": 50, "bag": 40} count = 0 for price in cart.values(): if price >= 40: count += 1 print(count)
Read the code line by line, then type the output exactly.
your turnPick the right idea

ages = {"Sunny": 25, "Rocky": 30}. Which line prints 55?

Think about it, then pick one.

Loop Over Keys and Values with items()

The items() method gives you every pair of a dictionary: a key together with its value. In the for line, write two loop variables, and Python puts the key in the first and the value in the second.

Think of it like going through a stack of name badges with photos: on each one you see the name and the face at the same time.

PYTHONedit me
marks = {"Sunny": 82, "Rocky": 67, "Lucky": 91}
for name, mark in marks.items():
    print(name, "scored", mark)
OUTPUT
Sunny scored 82
Rocky scored 67
Lucky scored 91

The rules

  • for key, value in d.items(): with a comma between the two names.
  • The first name gets the key, the second gets the value, in every round.
  • Choose names that say what they hold: name, mark or item, price, not a, b.
  • The pairs come in the order the keys were added.

You'll learn more about pairs like these, called tuples, in chapter 14. For now, splitting each pair into two loop variables is all you need.

Neat output with f-strings

Pair items() with the f-string widths from chapter 12, and you get a tidy table:

PYTHONedit me
menu = {"tea": 15, "coffee": 25, "sandwich": 60}
for item, price in menu.items():
    print(f"{item:<10}{price:>4}")
OUTPUT
tea         15
coffee      25
sandwich    60

Find the best key

With the key and value side by side, you can remember who had the top value, the way you found the largest number in chapter 10:

PYTHONedit me
marks = {"Sunny": 82, "Rocky": 67, "Lucky": 91}
best_name = ""
best_mark = -1
for name, mark in marks.items():
    if mark > best_mark:
        best_name = name
        best_mark = mark
print("Top:", best_name, best_mark)
OUTPUT
Top: Lucky 91

Avoid: two variables without items()

Looping over the dictionary itself gives only keys, and one key can't be split into two names:

PYTHONedit me
ages = {"Sunny": 25, "Rocky": 30}
for name, age in ages:
    print(name, age)
OUTPUT
ValueError: too many values to unpack (expected 2)

The fix is to add .items() after ages.

for key, value in d.items(): gives you each key and its value together.

your turnPredict the output

What will this print?

stock = {"pen": 3, "ink": 0} for item, n in stock.items(): if n == 0: print(item, "is sold out")
Your turn! What will this code show on the screen?
your turnSpot the bug

Which line breaks?

One line stops this program. Tap it.

Count Things with a Dictionary

A dictionary makes a perfect counter: each thing you count is a key, and its value is how many times you've seen it. One loop counts every different thing at once.

Think of it like a tally sheet at an election: each name gets its own row, and every vote adds one mark to that row.

PYTHONedit me
votes = ["Sunny", "Rocky", "Sunny", "Lucky", "Sunny", "Rocky"]
count = {}
for name in votes:
    count[name] = count.get(name, 0) + 1
print(count)
OUTPUT
{'Sunny': 3, 'Rocky': 2, 'Lucky': 1}

How the counting line works

count[name] = count.get(name, 0) + 1 does it all in one line:

  1. count.get(name, 0) reads the count so far, or 0 if the name is new.
  2. + 1 adds this vote.
  3. count[name] = … stores the new count, adding the key if it's new.

The same with in

If the get() line looks too clever, in and if from this chapter do the same job:

PYTHONedit me
count = {}
for ch in "banana":
    if ch in count:
        count[ch] += 1
    else:
        count[ch] = 1
print(count)
OUTPUT
{'b': 1, 'a': 3, 'n': 2}

The keys appear in the order each letter is first seen: b, then a, then n.

Print the counts nicely

Once counting is done, loop over items() to show the result:

PYTHONedit me
count = {}
for word in "the cat and the dog and the bird".split():
    count[word] = count.get(word, 0) + 1
for word, n in count.items():
    print(word, n)
OUTPUT
the 3
cat 1
and 2
dog 1
bird 1

split() from chapter 12 cuts the sentence into a list of words. Then each word is counted.

Avoid: += on a new key

count[name] += 1 on its own fails the first time a name appears, with a KeyError, because there's no old value yet (topic 3). Use get(name, 0) + 1, or the in check.

Count with d[key] = d.get(key, 0) + 1: new keys start at 0, old ones go up by one.

your turnFix the code

Count each fruit

It should print: {'apple': 2, 'kiwi': 1}

basket = ["apple", "kiwi", "apple"]
count = {}
for fruit in basket:
    count[fruit] += 1
print(count)
This code does not work yet. Fix it, then press Run.
your turnPredict the output

What will this print?

words = "red blue red".split() print(words)
Your turn! What will this code show on the screen?

Lists of Dictionaries and Dictionaries of Lists

Lists and dictionaries can hold each other. A list of dictionaries stores many records with the same keys, like a table. A dictionary of lists stores several values under each key.

Think of it like a class register: the register is a list, and each student's row is a dictionary with a name and a mark.

A list of dictionaries

PYTHONedit me
students = [
    {"name": "Sunny", "mark": 82},
    {"name": "Rocky", "mark": 67},
]
for student in students:
    print(student["name"], "got", student["mark"])
OUTPUT
Sunny got 82
Rocky got 67

Each round of the loop gets one whole dictionary in student. Then student["name"] reads a key from it.

Two steps to reach a value

Read from the outside in: first the list index, then the key.

PYTHONedit me
students = [
    {"name": "Sunny", "mark": 82},
    {"name": "Rocky", "mark": 67},
]
print(students[1]["name"])
students[0]["mark"] = 85
print(students[0])
OUTPUT
Rocky
{'name': 'Sunny', 'mark': 85}

students[1] is Rocky's dictionary, and ["name"] reads his name from it.

A dictionary of lists

Here each key holds a list, so one student can have many marks:

PYTHONedit me
marks = {"Sunny": [80, 92], "Rocky": [70, 64, 75]}
marks["Sunny"].append(88)
for name, scores in marks.items():
    print(name, scores, "best:", max(scores))
OUTPUT
Sunny [80, 92, 88] best: 92
Rocky [70, 64, 75] best: 75

marks["Sunny"] is a list, so every list tool from chapter 9 works on it: append(), max(), len().

Which one?

ShapeLooks likeGood for
list of dictionaries[{"name": "Sunny"}, …]many records with the same keys
dictionary of lists{"Sunny": [80, 92], …}many values for each key

Common beginner doubt: "How deep can this go?" As deep as you like, but keep it to two levels while you're learning. If you need three pairs of brackets to reach a value, your data might be easier as two simpler pieces.

Read nested data from the outside in: students[0]["name"], marks["Sunny"][1].

your turnType the output

Type what this prints

team = [{"name": "Sunny", "goals": 2}, {"name": "Lucky", "goals": 5}] print(team[1]["goals"] + team[0]["goals"])
Read the code line by line, then type the output exactly.
your turnPick the right idea

marks = {"Sunny": [80, 92], "Rocky": [70, 64]}. Which gives Rocky's first mark, 70?

Think about it, then pick one.

Practice: Looping

Solve these to lock in what you learned in this topic. Each one runs in your browser.

  1. 117.Python Program to Print a Menu from a DictionaryEasySolve
  2. 118.Python Program to Count Each Letter in a WordMediumSolve
  3. 119.Python Program to Manage a Shop InventoryHardSolve