57 — Group: data by category
Counting (guides 36 and 54) answers how many; grouping answers how many per category: it splits one list of dicts into lists, one per value of a key.
Steps
Create
data.json, a list of dicts — each has aname,category,price:
run it →[ {"name": "Mina", "category": "fruit", "price": 3}, {"name": "Jun", "category": "veggie", "price": 2}, {"name": "Sora", "category": "fruit", "price": 5}, {"name": "Tom", "category": "veggie", "price": 1}, {"name": "Ari", "category": "fruit", "price": 4} ]Load it with
json_loadfrom guide 14. The manual group uses theif word in tallyidea from guide 36 — a new category starts an empty list:
run it →use file latest items = json_load("data.json") groups = {} for item in items: cat = item["category"] if cat not in groups: groups[cat] = [] groups[cat].append(item)setdefaultdoes the "new key gets an empty list" step in one call, thenappendalways works — the shorter spelling of the same loop:
run it →quick = {} for item in items: quick.setdefault(item["category"], []).append(item)The full program groups, reports counts and totals, and proves
setdefaultagrees. Save it asgroup.nme:
run it →# group.nme — group a list of dicts by category, then report counts. # Run: nme r group use file latest items = json_load("data.json") show "loaded " + str(len(items)) + " items" groups = {} for item in items: cat = item["category"] if cat not in groups: groups[cat] = [] groups[cat].append(item) show "counts per category:" for cat in groups: show cat + ": " + str(len(groups[cat])) + " items" show "total price per category:" for cat in groups: total = 0 for item in groups[cat]: total = total + item["price"] show f"{cat}: ${total}" quick = {} for item in items: quick.setdefault(item["category"], []).append(item) show "setdefault agrees:" for cat in quick: show f"{cat}: {len(quick[cat])} items"The outer loop walks categories, the inner loop walks each category's items.
Run it with
data.jsonin the folder:nme r grouploaded 5 items counts per category: fruit: 3 items veggie: 2 items total price per category: fruit: $12 veggie: $3 setdefault agrees: fruit: 3 items veggie: 2 itemsEach category is a list, so the report can count it, name it, or add prices.
Try it yourself
Group by price instead of category — every price is its own group, showing
which items cost the same.
What you learned
- Grouping splits one list of dicts into a dict of lists by a key's value.
if cat not in groupsstarts a new list;groups[cat].append(item)fills it.groups.setdefault(cat, []).append(item)is the same in one call.- The outer loop walks categories; the inner loop walks each category's items.