CurriculumPython Dictionaries for KidsTally and group
Counting and Grouping with a Python Dictionary
A dict can count things for you — one running total per key, all through one loop.
Tally and group
You've built running totals before, in a loop. Now you'll build MANY of them at once — one per key.
drops = ["gold", "gem", "gold", "sword", "gold"]. To count how many of each item dropped, start with an EMPTY dict.
drops = ["gold", "gem", "gold", "sword", "gold"]
counts = {}For each item, check if it's already a key. If it is, add 1 to its count. If it isn't, this is the FIRST time — start it at 1.
for item in drops:
if item in counts:
counts[item] = counts[item] + 1
else:
counts[item] = 1
print(counts)Output
{'gold': 3, 'gem': 1, 'sword': 1}Here's the trap. Skip the if/else and just write counts[item] = counts[item] + 1 every time — it looks like the same idea, shorter.
The FIRST time an item shows up, counts[item] on the right side is reading a key that was never set — that's a real KeyError, same crash s3 taught, just hiding inside a loop this time.
counts = {}
for item in drops:
counts[item] = counts[item] + 1Output
KeyError: 'gold'The elegant fix reuses .get() from segment 3: counts[item] = counts.get(item, 0) + 1. When the key is missing, .get() hands back 0 instead of crashing — so "0 + 1" becomes the key's first count, all in one line.
counts = {}
for item in drops:
counts[item] = counts.get(item, 0) + 1
print(counts)Output
{'gold': 3, 'gem': 1, 'sword': 1}Same result either way — if/else spells out the two cases, .get() folds them into one. Both are real Python; pick whichever reads clearer to you.
Check your understanding
counts = {}. drops = ["gold", "gem"]. This code runs for EVERY item: counts[item] = counts[item] + 1 — no if/else, no .get(). What happens on the very first pass?
counts = {}
for item in drops:
counts[item] = counts[item] + 1Why: A KeyError. counts[item] = counts[item] + 1 has to READ counts[item] first to add 1 to it — and the first time an item appears, that key doesn't exist yet. Either check "if item in counts" first, or use counts.get(item, 0) + 1 so the missing case has a safe default built in.
counts = {}. drops = ["ice", "ice"]. Using counts[item] = counts.get(item, 0) + 1 each pass, what does counts["ice"] equal after BOTH passes?
counts = {}
for item in ["ice", "ice"]:
counts[item] = counts.get(item, 0) + 1
print(counts["ice"])Why: 2. Pass one: "ice" isn't a key yet, so .get("ice", 0) returns 0, and counts["ice"] becomes 0 + 1 = 1. Pass two: "ice" IS a key now, so .get("ice", 0) returns the real 1, and counts["ice"] becomes 1 + 1 = 2.
What you'll practice
drops = ["gold", "gem", "gold"]. This code is trying to COUNT how many times each item drops — but it crashes with a KeyError the very first time it sees an item, because it reads counts[item] before that key has ever been set. Run it once to see the real error, then fix it so a brand-new key gets a safe starting value.
More from this topic
Tally and group is one lesson inside Python Dictionaries for Kids — see the full lesson order and what the whole topic covers.
View the full topic →