Picture a client record in your project tracker. It has a name field, a rate field, an hours field, a status. You look them up by field name, not by column number. That is a Python dict.
Wait — so a dict is literally a client record? Like a row in my Notion database where I know what each cell means by name?
Exactly that. client = {"name": "Acme", "rate": 120.0, "hours": 4.5} — ask for client["rate"] and you get 120.0. No VLOOKUP, no column-counting. Now to group by status: build an accumulator dict where each key is a status string and each value is a list of clients with that status:
groups = {}
for c in clients:
status = categorize_project_status(c["hours"], c.get("budgeted", c["hours"]))
groups.setdefault(status, []).append(c)Why .get() instead of groups[status]? I have seen .get() before but I keep defaulting to bracket access.
Bracket access raises KeyError if the key does not exist yet. .get(key, default) returns the default safely. For a new status group, groups.get("on track", []) returns [] instead of crashing. Chain with .setdefault() to create the key if missing and append in one step.
So the result is {"on track": [...clients...], "critical": [...clients...]} — I can iterate .items() to print the report.
Wait until you iterate .items() across six clients and print a grouped monthly report in three lines. That is exactly it:
def group_by_status(clients: list) -> dict:
groups = {}
for c in clients:
status = c.get("status", "on track")
if status not in groups:
groups[status] = []
groups[status].append(c)
print(f"Groups: {list(groups.keys())}")
return groupsMy monthly sort-by-status is now a function that takes two seconds.
.keys() gives you the group names, .values() gives the lists of clients, .items() gives both. Learn all three — you will use each one in the next two days.
.get()groups = {}
for c in clients:
status = categorize_project_status(c['actual'], c['budgeted'])
groups[status] = groups.get(status, []) + [c].get(key, default) returns the value for key if it exists, or default if not. Using [] as the default avoids a KeyError on the first client in each group.
.keys(), .values(), .items() iterate over the keys, values, or both as (key, value) pairs. Use .items() when you need both in the same loop:
for status, group in groups.items():
print(status, len(group))The final dict has one key per status and a list of client dicts as the value.
Picture a client record in your project tracker. It has a name field, a rate field, an hours field, a status. You look them up by field name, not by column number. That is a Python dict.
Wait — so a dict is literally a client record? Like a row in my Notion database where I know what each cell means by name?
Exactly that. client = {"name": "Acme", "rate": 120.0, "hours": 4.5} — ask for client["rate"] and you get 120.0. No VLOOKUP, no column-counting. Now to group by status: build an accumulator dict where each key is a status string and each value is a list of clients with that status:
groups = {}
for c in clients:
status = categorize_project_status(c["hours"], c.get("budgeted", c["hours"]))
groups.setdefault(status, []).append(c)Why .get() instead of groups[status]? I have seen .get() before but I keep defaulting to bracket access.
Bracket access raises KeyError if the key does not exist yet. .get(key, default) returns the default safely. For a new status group, groups.get("on track", []) returns [] instead of crashing. Chain with .setdefault() to create the key if missing and append in one step.
So the result is {"on track": [...clients...], "critical": [...clients...]} — I can iterate .items() to print the report.
Wait until you iterate .items() across six clients and print a grouped monthly report in three lines. That is exactly it:
def group_by_status(clients: list) -> dict:
groups = {}
for c in clients:
status = c.get("status", "on track")
if status not in groups:
groups[status] = []
groups[status].append(c)
print(f"Groups: {list(groups.keys())}")
return groupsMy monthly sort-by-status is now a function that takes two seconds.
.keys() gives you the group names, .values() gives the lists of clients, .items() gives both. Learn all three — you will use each one in the next two days.
.get()groups = {}
for c in clients:
status = categorize_project_status(c['actual'], c['budgeted'])
groups[status] = groups.get(status, []) + [c].get(key, default) returns the value for key if it exists, or default if not. Using [] as the default avoids a KeyError on the first client in each group.
.keys(), .values(), .items() iterate over the keys, values, or both as (key, value) pairs. Use .items() when you need both in the same loop:
for status, group in groups.items():
print(status, len(group))The final dict has one key per status and a list of client dicts as the value.
Liv reviews her six clients each month and needs them grouped by project status for a clean report. Write `group_by_status(clients)` that groups client dicts by their `status` field (each dict has at minimum `name` and `status` keys) and returns a dict mapping status strings to lists of client dicts.
Tap each step for scaffolded hints.
No blank-editor panic.