Pivot a list of row dicts into per-column lists by looping over the records and appending each field to its column accumulator. The pandas version passes the same list-of-dicts directly to pd.DataFrame, which performs the same pivot internally and returns a two-dimensional structure with an aligned index.

By hand

Loop over each record r, appending each field to its dedicated column list. After the loop, the three lists collectively form a columnar table.

naive.py
Replay: real traced execution (multi-file project)
# trace: ignore records
records = [
    {'name': 'al', 'age': 20, 'score': 80},
    {'name': 'bo', 'age': 25, 'score': 90},
    {'name': 'cy', 'age': 22, 'score': 70},
    {'name': 'di', 'age': 28, 'score': 85},
]
names = []
ages = []
scores = []
for r in records:
    names.append(r['name'])
    ages.append(r['age'])
    scores.append(r['score'])
print('RESULT:', sorted(['name', 'age', 'score']))
  1. {'name': 'al', 'age': 20, 'score': 80},

    2records = [3    {'name': 'al', 'age': 20, 'score': 80},4    {'name': 'bo', 'age': 25, 'score': 90},
  2. {'name': 'bo', 'age': 25, 'score': 90},

    3{'name': 'al', 'age': 20, 'score': 80},4{'name': 'bo', 'age': 25, 'score': 90},5{'name': 'cy', 'age': 22, 'score': 70},
  3. {'name': 'cy', 'age': 22, 'score': 70},

    4{'name': 'bo', 'age': 25, 'score': 90},5{'name': 'cy', 'age': 22, 'score': 70},6{'name': 'di', 'age': 28, 'score': 85},
  4. {'name': 'di', 'age': 28, 'score': 85},

    5    {'name': 'cy', 'age': 22, 'score': 70},6    {'name': 'di', 'age': 28, 'score': 85},7]
  5. records = [

    1# trace: ignore records2records = [3    {'name': 'al', 'age': 20, 'score': 80},
  6. names ← []

    7]8names = []9ages = []
    values this step[]names
  7. ages ← []

    8names = []9ages = []10scores = []
    values this step[]ages
  8. scores ← []

    9ages = []10scores = []11for r in records:
    values this step[]scores
  9. r ← {'name': 'al', 'age': 20, 'score': 80}

    10scores = []11for r in records:12    names.append(r['name'])
    values this step{'name': 'al', 'age': 20, 'score': 80}r
  10. names ← ['al']

    11for r in records:12    names.append(r['name'])13    ages.append(r['age'])
    values this step[] ['al']names
  11. ages ← [20]

    12names.append(r['name'])13ages.append(r['age'])14scores.append(r['score'])
    values this step[] [20]ages
  12. scores ← [80]

    13    ages.append(r['age'])14    scores.append(r['score'])15print('RESULT:', sorted(['name', 'age', 'score']))
    values this step[] [80]scores
  13. r ← {'name': 'bo', 'age': 25, 'score': 90}

    10scores = []11for r in records:12    names.append(r['name'])
    values this step{'name': 'al', 'age': 20, 'score': 80} {'name': 'bo', 'age': 25, 'score': 90}r
  14. names ← ['al', 'bo']

    11for r in records:12    names.append(r['name'])13    ages.append(r['age'])
    values this step['al'] ['al', 'bo']names
  15. ages ← [20, 25]

    12names.append(r['name'])13ages.append(r['age'])14scores.append(r['score'])
    values this step[20] [20, 25]ages
  16. scores ← [80, 90]

    13    ages.append(r['age'])14    scores.append(r['score'])15print('RESULT:', sorted(['name', 'age', 'score']))
    values this step[80] [80, 90]scores
  17. r ← {'name': 'cy', 'age': 22, 'score': 70}

    10scores = []11for r in records:12    names.append(r['name'])
    values this step{'name': 'bo', 'age': 25, 'score': 90} {'name': 'cy', 'age': 22, 'score': 70}r
  18. names ← ['al', 'bo', 'cy']

    11for r in records:12    names.append(r['name'])13    ages.append(r['age'])
    values this step['al', 'bo'] ['al', 'bo', 'cy']names
  19. ages ← [20, 25, 22]

    12names.append(r['name'])13ages.append(r['age'])14scores.append(r['score'])
    values this step[20, 25] [20, 25, 22]ages
  20. scores ← [80, 90, 70]

    13    ages.append(r['age'])14    scores.append(r['score'])15print('RESULT:', sorted(['name', 'age', 'score']))
    values this step[80, 90] [80, 90, 70]scores
  21. r ← {'name': 'di', 'age': 28, 'score': 85}

    10scores = []11for r in records:12    names.append(r['name'])
    values this step{'name': 'cy', 'age': 22, 'score': 70} {'name': 'di', 'age': 28, 'score': 85}r
  22. names ← ['al', 'bo', 'cy', 'di']

    11for r in records:12    names.append(r['name'])13    ages.append(r['age'])
    values this step['al', 'bo', 'cy'] ['al', 'bo', 'cy', 'di']names
  23. ages ← [20, 25, 22, 28]

    12names.append(r['name'])13ages.append(r['age'])14scores.append(r['score'])
    values this step[20, 25, 22] [20, 25, 22, 28]ages
  24. scores ← [80, 90, 70, 85]

    13    ages.append(r['age'])14    scores.append(r['score'])15print('RESULT:', sorted(['name', 'age', 'score']))
    values this step[80, 90, 70] [80, 90, 70, 85]scores
  25. for r in records:

    10scores = []11for r in records:12    names.append(r['name'])
  26. stdout ← RESULT: ['age', 'name', 'score']

    14    scores.append(r['score'])15print('RESULT:', sorted(['name', 'age', 'score']))
    values this stepRESULT: ['age', 'name', 'score']stdout

With pandas

pd.DataFrame(records) accepts a list of dicts and builds a DataFrame with one column per key. The snapshot shows the column names, shape, and each column's values.

library.py
import pandas as pd
from dalib.display import set_display
set_display()

records = [
    {'name': 'al', 'age': 20, 'score': 80},
    {'name': 'bo', 'age': 25, 'score': 90},
    {'name': 'cy', 'age': 22, 'score': 70},
    {'name': 'di', 'age': 28, 'score': 85},
]
df = pd.DataFrame(records)
print('columns:', df.columns.tolist())
print('shape:', df.shape)
print('name:', df['name'].tolist())
print('age:', df['age'].tolist())
print('score:', df['score'].tolist())
print('RESULT:', sorted(df.columns.tolist()))
columns: ['name', 'age', 'score']
shape: (4, 3)
name: ['al', 'bo', 'cy', 'di']
age: [20, 25, 22, 28]
score: [80, 90, 70, 85]
RESULT: ['age', 'name', 'score']

Implementation notes

  • A DataFrame is a collection of Series columns sharing one index. Each column is a typed 1D array (dtype per column); the shared index aligns rows across columns, just as the record position did in the naive loop.
  • df.shape returns (rows, columns) — the 2D analogue of len() on a Series.
  • pd.DataFrame also accepts a dict of column-lists ({'name': [...], ...}), which mirrors the columnar layout of the hand-written names, ages, scores lists.
  • The records variable is excluded from the trace with # trace: ignore records because its repr (160 chars) exceeds the 80-char display limit; each per-record dict r remains visible in the loop.