Derive row count, column count, and sorted column names from a list of records using len and a key-extraction loop. With pandas, df.shape and df.columns expose the same facts directly as attributes on the DataFrame.

By hand

Count rows with len(records). Extract column names by looping over the keys of the first record and collecting them into cols. Sort to get a stable order.

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},
]
n_rows = len(records)
cols = []
for k in records[0]:
    cols.append(k)
cols = sorted(cols)
n_cols = len(cols)
print('RESULT:', (n_rows, n_cols, cols))
  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. n_rows ← 4

    7]8n_rows = len(records)9cols = []
    values this step4n_rows
  7. cols ← []

    8n_rows = len(records)9cols = []10for k in records[0]:
    values this step[]cols
  8. k ← 'name'

    9cols = []10for k in records[0]:11    cols.append(k)
    values this step'name'k
  9. cols ← ['name']

    10for k in records[0]:11    cols.append(k)12cols = sorted(cols)
    values this step[] ['name']cols
  10. k ← 'age'

    9cols = []10for k in records[0]:11    cols.append(k)
    values this step'name' 'age'k
  11. cols ← ['name', 'age']

    10for k in records[0]:11    cols.append(k)12cols = sorted(cols)
    values this step['name'] ['name', 'age']cols
  12. k ← 'score'

    9cols = []10for k in records[0]:11    cols.append(k)
    values this step'age' 'score'k
  13. cols ← ['name', 'age', 'score']

    10for k in records[0]:11    cols.append(k)12cols = sorted(cols)
    values this step['name', 'age'] ['name', 'age', 'score']cols
  14. for k in records[0]:

    9cols = []10for k in records[0]:11    cols.append(k)
  15. cols ← ['age', 'name', 'score']

    11    cols.append(k)12cols = sorted(cols)13n_cols = len(cols)
    values this step['name', 'age', 'score'] ['age', 'name', 'score']cols
  16. n_cols ← 3

    12cols = sorted(cols)13n_cols = len(cols)14print('RESULT:', (n_rows, n_cols, cols))
    values this step3n_cols
  17. stdout ← RESULT: (4, 3, ['age', 'name', 'score'])

    13n_cols = len(cols)14print('RESULT:', (n_rows, n_cols, cols))
    values this stepRESULT: (4, 3, ['age', 'name', 'score'])stdout

With pandas

df.shape returns a (rows, cols) tuple. df.columns is an Index of column labels; .tolist() converts it to a plain Python list.

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)
cols = sorted(df.columns.tolist())
print('shape:', df.shape)
print('columns:', df.columns.tolist())
print('RESULT:', (df.shape[0], df.shape[1], cols))
shape: (4, 3)
columns: ['name', 'age', 'score']
RESULT: (4, 3, ['age', 'name', 'score'])

Implementation notes

  • df.shape is a property, not a method — no parentheses. It returns a plain Python tuple, so df.shape[0] (row count) and df.shape[1] (column count) work without any conversion.
  • df.columns is a pandas Index object, not a list. It supports label lookup, set operations (union, intersection), and alignment — calling .tolist() drops those capabilities and gives a plain Python list for stable comparison or printing.
  • Column order reflects insertion order (the key order of the first record when built from a list-of-dicts). sorted() gives a deterministic order for comparison, as in the naive loop.
  • df.dtypes gives the dtype of every column at once; df.info() gives shape, column names, dtypes, and memory usage in one call.