1.2.26 · D1Introduction to Programming (Python)

Foundations — Nested data structures — list of dicts, dict of lists

2,120 words10 min readBack to topic

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

Figure — Nested data structures — list of dicts, dict of lists

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

Figure — Nested data structures — list of dicts, dict of lists

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

Figure — Nested data structures — list of dicts, dict of lists

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

Value number or string

List ordered numbered boxes

Dict labelled boxes key to value

Bracket indexing take a slot

Chained brackets dive twice

Nesting box inside a box

len count of items

for visit each item

Comprehension one line loop

Mutable edit in place

Nested data structures LoD and DoL


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?
A number when 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?
The number of rows (top-level list slots).
What does a list comprehension [m+5 for m in xs] produce?
A brand-new list with m+5 for each m in xs.
Why does dict.fromkeys(cols, []) cause a shared-list bug?
All keys point to the same mutable list object; editing one edits all.

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 for of §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