1.2.26 · D2Introduction to Programming (Python)

Visual walkthrough — Nested data structures — list of dicts, dict of lists

2,210 words10 min readBack to topic

Before we begin, a promise about vocabulary. We will use exactly these plain-English words and earn each one on a picture:

  • a cell = one single fact (Asha's marks: 88),
  • a row = all facts about one thing (everything about Asha),
  • a column = one kind of fact across all things (marks of everyone).

Prerequisites we lean on: Lists (an ordered shelf you index by position 0,1,2,…), Dictionaries (a labelled drawer you open by name/key), and List Comprehensions (a compact sentence that builds a list). If any of those feel shaky, open them first.


Step 1 — Start with a bare grid (no Python yet)

WHAT. Forget code. Draw the data as a plain table: names down the side of the thinking, facts in cells.

WHY. Both structures we are about to build store this exact grid. If we anchor the grid first, every later shape is just "how do I walk this grid?" — nothing new to memorise.

PICTURE. Three things (Asha, Ravi, Meera), each with three facts (name, age, marks). The red cell is the one fact we will chase through every diagram: Ravi's marks = 73.

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

Step 2 — Slice the grid into ROWS → the List of Dicts

WHAT. Cut the grid with horizontal cuts. Each horizontal strip is one whole thing. Pack each strip into a labelled drawer — a dict {column: value} — and line the drawers up on a shelf — a list.

WHY horizontal? Because the most common real question is "give me everything about one record" (one API result, one form submission). Horizontal strips make that a single grab.

PICTURE. Watch the red cell 73: it lands inside the second drawer (Ravi's), under the label marks.

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

Step 3 — Slice the SAME grid into COLUMNS → the Dict of Lists

WHAT. Now cut the same grid with vertical cuts. Each vertical strip is one kind of fact for everybody. Give each strip a name (marks) and store the strip as a list, then keep those named lists in a dict.

WHY vertical? Because the other common question is "do maths on one whole column" (average of all marks). A vertical strip is already a flat list of numbers — ready to sum.

PICTURE. The red 73 now lives in the marks list, at position 1. Nothing about the data changed — only the direction of the cuts.

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

Step 4 — Put the two readings side by side: the index crosses over

WHAT. Line up the two formulas for the very same red cell and stare at them.

WHY. This is the whole point of the parent note. Seeing the symbols swap positions is what "transpose" means — not a vague analogy, a literal reordering of the same two coordinates.

PICTURE. The red arrow shows i and c trading seats as you go from LoD to DoL.

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

Step 5 — Column maths: WHY DoL wins (derive the average)

WHAT. Compute the average marks in both shapes and count the work.

WHY. The parent claims DoL is better for column maths. Let's see the extra work LoD forces.

PICTURE. On the left (LoD) the marks are scattered across three drawers — the red loop must visit each drawer and pull one fact out (a gather). On the right (DoL) the marks are already a single red strip — sum walks it directly, no gathering.

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

Step 6 — Build the conversion LoD → DoL (the code writes itself)

WHAT. Turn the shelf of drawers (Step 2) into the dict of strips (Step 3), using only what the pictures already showed.

WHY. Because now the loop is the picture: "for each column label, walk every row and collect that label's value in order" — that is Step 3's vertical cut, spoken aloud.

PICTURE. Highlighted in red: one column being assembled by sweeping down through every drawer.

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

Step 7 — Build the reverse, DoL → LoD

WHAT. Rotate back: dict of strips → shelf of drawers.

WHY. Same idea, other axis. Now we fix a row index i and read the i-th cell of every column — that is a horizontal cut (Step 2), spoken aloud. This is literally turning students[c][i] back into students[i][c].

PICTURE. Red: one row being rebuilt by reaching into position i of each column strip.

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

Step 8 — Degenerate cases (never hit a scenario we didn't show)

WHAT. The rotation has sharp edges. Four to know, each with the picture of what breaks.

WHY. The contract: cover every case, including empty and ragged data, so you are never surprised.

PICTURE. Left: an empty grid. Middle: a ragged grid (Ravi's drawer is missing marks). Right: the "shared strip" trap where two column labels secretly point at one physical list.

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

The one-picture summary

Everything above, compressed: the same grid, cut two ways, with the red cell 73 findable by [1]["marks"] on the left and ["marks"][1] on the right — indices crossing over, that is the transpose.

Figure — Nested data structures — list of dicts, dict of lists
Recall Feynman retelling (plain words)

Picture a class scoreboard drawn as a table. If you snip it into horizontal strips, each strip is one kid's whole story — put each strip in a labelled drawer and stand the drawers on a shelf: that's a list of dicts. To find Ravi's marks you say "drawer number 1, open the marks label" → [1]["marks"]. If instead you snip the same table into vertical strips, each strip is one kind of fact for everyone — name each strip and keep them in one cupboard: that's a dict of lists. Now to find Ravi's marks you say "the marks strip, line number 1" → ["marks"][1]. Same fact, but the two words you speak have swapped order — that swap is the whole secret, the "transpose". Vertical strips make adding up a whole column trivial (they're already in a line); horizontal drawers make grabbing or adding one kid trivial (one self-contained card). Converting between them is just re-snipping the table the other way — a loop over labels for one direction, a loop over positions for the other. Watch out for empty tables, drawers missing a label, strips of unequal length, and the sneaky bug where two labels point at the very same physical strip.

Connections

  • Yeh note Hinglish mein → — same walkthrough, Hinglish
  • Lists — the shelf of drawers / the column strips
  • Dictionaries — the labelled drawers / the cupboard of strips
  • List Comprehensions — the engine that re-snips the grid
  • Loops and Iteration — the vertical and horizontal sweeps
  • Mutable vs Immutable — why the shared-strip bug (Case D) bites
  • Pandas DataFrame — the column-first (DoL) idea, industrial strength
  • JSON and APIs — where list-of-dicts data usually arrives from