The Roll Call

An easy Python interview practice problem on DataDriven. Write the Python and run it against test cases, with instant feedback.

Domain
Python
Difficulty
easy
Seniority
L3

Problem

A CSV reader hands you the column names in headers and the table body in rows, where each row is a list of values positionally aligned to those headers. Return one dict per row that maps each column name to that row's value.

Every value is waiting for its name.

Example

Input:

rows = [["Alice","30","Boston"],["Bob","25","NYC"]], headers = ["name","age","city"]

Output:

[{"age":"30","city":"Boston","name":"Alice"},{"age":"25","city":"NYC","name":"Bob"}]

Worked solution and explanation

What this really is

This is positional alignment wearing a data-parsing costume. The whole problem is gluing two parallel sequences together by index: the header at position i names the value at position i, for every row. Almost everyone reaches for a manual range(len(headers)) index loop, and it works on the happy path. The tell of a stronger candidate is recognizing that Python already has the exact primitive for walking two lists in lockstep, so they never write an index variable at all. Reach for indices here and you also hand-roll the off-by-one risk that the primitive eliminates for free.


The move

Step 1: Pair, don't index

zip(headers, row) yields (header, value) pairs in order, so you never touch an index. Feed those pairs straight into dict(...) and you have one record. This is the single insight the problem is probing.

Step 2: Map it across every row

Wrap that per-row expression in a comprehension over rows. One flat, readable line builds the whole list of records, and an empty rows naturally yields an empty list with no special case.

Header-to-row zipping into dicts
def rows_to_dicts(headers, rows):
    return [dict(zip(headers, row)) for row in rows]
Manual indexing
for i in range(len(headers)): record[headers[i]] = row[i] Same compute, but you introduce an index variable, a mutable dict, and an off-by-one surface for no benefit.
zip
dict(zip(headers, row)) No index, no manual mutation, reads as exactly what it does: pair the columns with the values.

Common follow-up questions