Foundations — Nested data structures — list of dicts, dict of lists
Before you touch nested structures you must be fluent in the pieces they are made of. This page builds every one of those pieces from nothing — a smart 12-year-old who has only seen a variable like x = 5 should finish able to read students[0]["name"] out loud and know exactly what happens.
1. A value — the atom
Picture: a value is one dot on the blueprint. Nothing is nested yet.
Why the topic needs it: every cell in our data table (a name, an age, a mark) is one value. Lists and dicts are just containers of values.
2. The list — an ordered row of numbered boxes

Look at the figure: the boxes are numbered 0, 1, 2 under them, in cyan. The value 88 lives at index 0, 73 at index 1, 95 at index 2.
Why the topic needs it: the rows of a list-of-dicts, and the column strips of a dict-of-lists, are both lists. You cannot escape it.
Link: Lists.
3. Square-bracket indexing — the "open box, take slot" operation
Picture: an amber arrow diving into box 1 and pulling out 73. That arrow is what [...] is.
Why the topic needs it: every access in the parent note — students[0], students["name"], students[0]["name"] — is one or more of these bracket dives, chained. Master one dive and the chain is easy.
4. The dict — labelled boxes instead of numbered ones

In the figure the boxes have word labels on them (name, age, marks) instead of numbers underneath. That is the whole difference between a dict and a list.
Why the topic needs it: in a list-of-dicts, each row is a dict; in a dict-of-lists, the outer bundle is a dict whose keys are column names. Half the topic is dicts.
Link: Dictionaries.
5. Dict indexing — same brackets, but the label is a key
Why the topic needs it: the parent's core insight "peel outer container first, then inner" is entirely about knowing whether the box in your hand is a list (wants a number) or a dict (wants a key).
6. Nesting — a value can itself be a container

The figure shows both as a box-in-a-box: on the left an outer numbered box whose slots each contain a labelled dict; on the right an outer labelled box whose slots each contain a numbered list.
7. Chained brackets — dive twice
This is exactly why the parent note writes cells as students[i][c] (LoD) versus students[c][i] (DoL): whichever container is on the outside decides which label comes first.
8. len() — how many boxes?
Why the topic needs it: to average marks you divide by the number of rows — that number is len(students) (LoD) or len(students["marks"]) (DoL).
9. for — visit every box in turn
Why the topic needs it: gathering a column out of a list-of-dicts (for row in lod) and building rows out of a dict-of-lists both ride on for.
Link: Loops and Iteration.
10. Comprehension — a loop compressed into one line
Why the topic needs it: the parent's transpose one-liner {k: [row[k] for row in lod] for k in lod[0]} is two nested comprehensions. You can't read it without this piece.
Link: List Comprehensions.
11. Mutable — boxes you can edit in place
Picture: two amber arrows from two keys landing on one single box. Change the box, both arrows still see the change.
Link: Mutable vs Immutable.
Prerequisite map
Equipment checklist
What symbol makes a list, and what makes a dict?
[ ] (square brackets) make a list; { } (curly braces) make a dict.What is the first index of any list?
0 — you count boxes past the front door, and the first is 0 steps past.Inside container[k], when is k a number and when is it a key?
container is a list; a key (usually a string) when it is a dict. Check the outer container's type first.What error do you get from marks["age"] on a list?
TypeError — a list only accepts integer positions.What error from asha[0] on a string-keyed dict?
KeyError — a dict only accepts its keys.In lod[0]["name"], why must [0] come before ["name"]?
lod is a list, so [0] first turns it into a dict; only then does the key "name" make sense.What does len(students) count in a list of dicts?
What does a list comprehension [m+5 for m in xs] produce?
m+5 for each m in xs.Why does dict.fromkeys(cols, []) cause a shared-list bug?
Connections
- Lists — the numbered-box container built in §2
- Dictionaries — the labelled-box container built in §4
- List Comprehensions — the one-line loop of §10
- Loops and Iteration — the
forof §9 - Mutable vs Immutable — the shared-box hazard of §11
- JSON and APIs — where real lists-of-dicts come from
- Pandas DataFrame — the professional dict-of-lists
- Parent topic