Learning Goals
3 minBy the end of this lesson you can:
- Loop a dictionary's keys (the default) and values (with
.values()). - Loop both at once with
for k, v in d.items():— tuple unpacking from PY-L2-04 in action. - Use
sum(),max()andmin()on values to answer real questions.
Warm-Up
5 minYesterday we ended with this dictionary:
stock = {"pencil": 50, "eraser": 30, "ruler": 12, "sharpener": 8}
How do you print a tidy list of items, one per line? Predict the output:
for item in stock: print(item, ":", stock[item])
Show the answer
pencil : 50 eraser : 30 ruler : 12 sharpener : 8
A bare for x in dict: walks the keys. We then have to look the value up by hand — a tiny step that .items() is about to remove.
Three matching methods give you three different lenses on a dictionary — keys only, values only, or pairs. Pick the lens that matches the question you're asking.
New Concept · Three Lenses
14 minLens 1 · .keys() — the labels
d.keys() gives you a view of every key. You don't usually need to write it explicitly — a bare for x in d: already walks the keys — but it's the explicit version when you want to be clear:
stock = {"pencil": 50, "eraser": 30, "ruler": 12} for item in stock.keys(): print("We sell:", item)
We sell: pencil We sell: eraser We sell: ruler
Lens 2 · .values() — the data only
d.values() gives you a view of every value, with no keys. Useful when you only care about the numbers.
stock = {"pencil": 50, "eraser": 30, "ruler": 12} total = sum(stock.values()) print("Total items in shop:", total) # → Total items in shop: 92 print("Biggest stack:", max(stock.values())) # → Biggest stack: 50
sum(), max() and min() all happily accept d.values() — they treat it like a list.
Lens 3 · .items() — pairs
Here's the star of the show. d.items() gives you a view of (key, value) tuples. Combined with tuple unpacking from PY-L2-04, it's the cleanest way to walk a dictionary.
stock = {"pencil": 50, "eraser": 30, "ruler": 12} for item, qty in stock.items(): print(item, "->", qty)
pencil -> 50 eraser -> 30 ruler -> 12
The loop variable became two — item for the key, qty for the value. No more stock[item] inside the loop.
Side-by-side comparison
Question Lens "List the item names" keys "Sum / max / min the numbers" values "Print each pair" items "Filter by value, print key" items "Find a key by its value" items
Membership checks
Two flavours, easy to mix up:
"pencil" in stock # True — pencil is a KEY "pencil" in stock.keys() # same as above 50 in stock.values() # True — 50 is one of the VALUES 50 in stock # ❌ False — 50 is not a key
If a sentence says "is there a pencil?", that's a key question — "pencil" in stock. If it says "is anything at fifty?", that's a value question — 50 in stock.values().
Worked Example · The Class Marks Report
12 minThe story
Cikgu Hadi keeps the class quiz scores in a dictionary mapping name → mark. He wants a quick report:
- How many students sat the quiz?
- What were the lowest, highest and average scores?
- Who passed? (A pass is 50 or above.)
- Did anyone score exactly 100?
Save as marks_report.py:
Code
# marks_report.py — three lenses on one dictionary marks = { "Aisyah": 92, "Wei Jie": 48, "Priya": 100, "Iman": 73, "Aizat": 55, } # 1 — how many students? print("Students :", len(marks)) # 2 — the numbers only — use .values() print("Lowest :", min(marks.values())) print("Highest :", max(marks.values())) print("Average :", sum(marks.values()) / len(marks)) # 3 — passes — needs name AND mark, so .items() print("Passed :") for name, mark in marks.items(): if mark >= 50: print(" -", name, "(", mark, ")") # 4 — perfect scorers if 100 in marks.values(): print("Yes! Someone got 100.") else: print("No perfect scores.")
Output
Students : 5 Lowest : 48 Highest : 100 Average : 73.6 Passed : - Aisyah ( 92 ) - Priya ( 100 ) - Iman ( 73 ) - Aizat ( 55 ) Yes! Someone got 100.
Read the diff
Look at each block. The question changes — so the lens changes. We never use the wrong one: a question about "just the numbers" uses .values(); a question that needs both name and mark uses .items(). Matching the lens to the question is the whole skill.
Dictionaries are one-way: marks["Aisyah"] is instant; finding who scored 100 needs a scan with .items():
for name, mark in marks.items(): if mark == 100: print(name, "scored 100!")
Try It Yourself
13 minThree exercises. Match the lens to the question.
You're given prices = {"nasi lemak": 8.00, "satay": 1.20, "milo": 4.50, "roti canai": 3.50}. Use .values() and sum() to print the total of all menu prices.
Hint
prices = {"nasi lemak": 8.00, "satay": 1.20, "milo": 4.50, "roti canai": 3.50} print("Menu total: RM", sum(prices.values())) # → Menu total: RM 17.2
The keys are dish names; the numbers are the prices. The question is about numbers only — use .values().
Same prices. Print every dish and its price on its own line, formatted like nasi lemak ........... RM 8.0 — exact spacing not important, just dish-then-price.
Hint
for dish, price in prices.items(): print(dish, "...... RM", price)
The question needs both pieces — use .items() with tuple unpacking.
Print only the dishes that cost less than RM 5.00. Use .items() with an if.
Hint
for dish, price in prices.items(): if price < 5.00: print(dish, "— RM", price)
You need both the key (to print) and the value (to check) — so .items() is right.
Mini-Challenge · The Library Stocktake
8 minBuild library.py. You're given a dictionary mapping book title → number of copies.
books = { "Harry Potter": 5, "Percy Jackson": 3, "Wings of Fire": 7, "Diary of a Wimpy Kid": 4, "Hunger Games": 2, "Charlotte's Web": 0, "Tom Gates": 6, }
Your file must:
- Print the total number of books in the library — use
.values()andsum(). - Print the number of different titles — use
len(books). - Print the title with the most copies — scan
.items()and trackbest_title, best_count. - Print every title that's out of stock (
count == 0) — loop with.items(). - Use
0 in books.values()to printSome titles are out of stock!orAll titles in stock!
Stretch goal. Print the average number of copies per title using sum(books.values()) / len(books).
Show one possible solution
# library.py — stocktake with three lenses books = { "Harry Potter": 5, "Percy Jackson": 3, "Wings of Fire": 7, "Diary of a Wimpy Kid": 4, "Hunger Games": 2, "Charlotte's Web": 0, "Tom Gates": 6, } print("Total copies :", sum(books.values())) print("Total titles :", len(books)) best_title = "" best_count = -1 for title, count in books.items(): if count > best_count: best_count = count best_title = title print("Top title :", best_title, "(", best_count, "copies )") print("Out of stock :") for title, count in books.items(): if count == 0: print(" -", title) if 0 in books.values(): print("Some titles are out of stock!") else: print("All titles in stock!") # Stretch print("Average :", sum(books.values()) / len(books))
Non-negotiables: one sum(books.values()), one len(books), one .items() scan that finds the top title, and one .items() loop with an if to find the zero-stock titles. Notice each lens matches its question.
Recap
3 minA dictionary gives you three matching ways to iterate. .keys() for the labels (same as the default loop). .values() for the data — perfect with sum, max and min. .items() for pairs, unpacked with for k, v in d.items(): — the workhorse loop. Membership checks split too: x in d tests keys, x in d.values() tests values.
Vocabulary Card
- .keys()
- A view of every key in the dictionary.
- .values()
- A view of every value. Works with
sum,max,min,in. - .items()
- A view of every
(key, value)tuple. Walk withfor k, v in d.items():. - view
- A lightweight, live link to the dictionary's data. It always reflects the current state.
Homework
4 minSave a new file letter_count.py. Count how many times each letter appears in the string "the quick brown fox jumps over the lazy dog".
Your file must:
- Start with an empty dict
counts = {}. - Loop through each character of the sentence. If the character is a space, skip it (
continue). - For each letter: if it's already a key, increase its value by 1. Otherwise add it with value 1. Use the
incheck. - Print the full
countsdictionary. - Use
.items()with anifto print only the letters that appeared more than once.
Stretch. Print the most-common letter (and how many times it appeared) by scanning .items().
Sample · letter_count.py
# letter_count.py — tally letters with a dict sentence = "the quick brown fox jumps over the lazy dog" counts = {} for ch in sentence: if ch == " ": continue if ch in counts: counts[ch] = counts[ch] + 1 else: counts[ch] = 1 print(counts) print("Letters appearing more than once:") for letter, count in counts.items(): if count > 1: print(" -", letter, ":", count) # Stretch — most common letter best_letter = "" best_count = 0 for letter, count in counts.items(): if count > best_count: best_count = count best_letter = letter print("Most common:", best_letter, "(", best_count, ")")
Non-negotiables: the empty-dict start, the if ch in counts branch, and one .items() loop with a filter. The pangram already contains every letter at least once — so the "more than once" list is the interesting one.