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.

Lesson 5 of 5PROAges 10+
See what PRO unlocks →

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] + 1

Output

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] + 1
  • A KeyError — counts["gold"] is read before "gold" was ever set
  • It works fine — counts["gold"] just starts at 0 automatically
  • It silently skips that item and moves to the next one

Why: 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"])
  • 2 — the first pass starts it at 1, the second pass adds 1 more
  • 1 — .get() resets the count back to its default every time it runs
  • 0 — .get() always returns the default, no matter what

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.

Unlock this lesson with PRO →

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 →