Lessons · Python · defaultdict adds keys
setdefault hands you the stored object
d.setdefault(k, []) stores an empty list under k if k is missing and returns whichever list is now stored, so appending to it changes the dict.
Hone is a place to practise programming. This is one of its lessons, written out in full and free to read without an account.
What it is for
Grouping rows by key is this one line: groups.setdefault(key, []).append(row). Knowing that the returned list is the stored list is what makes it work, and what surprises people.
How to think about it
Read setdefault as 'get, creating if missing'. The value you get back is the one inside the dict, not a copy, so mutating it is the point. collections.defaultdict(list) does the same with less typing.
Worked example
d = {}Empty.d.setdefault("k", []).append(1)Stores [] under 'k', returns it, appends 1 to it.print(d){'k': [1]}.
d.setdefault("k", []).append(2)'k' exists now, so the stored list comes back.print(d){'k': [1, 2]}.
print(d.setdefault("k", []))[1, 2]: the default is ignored when the key exists.Your turn
Group each row under its city.
groups.(row["city"], []).append(row)
Solve one with the tests running
The trap
The default is built every call, even when unused. setdefault(k, expensive()) pays for expensive() each time; defaultdict only builds on a miss.