Zip to Record
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 header row in our CSV exports can repeat a column name, and when it does, the cell further to the right is the one we keep. Given the header names in keys and one row's cells in the equal-length values, build the record that maps each column to its cell by position.
Two lists become one record.
Example 1
Input:
keys = ["name","age","city"], values = ["Alice",30,"NYC"]
Output:
{"name":"Alice","age":30,"city":"NYC"}Example 2
Input:
keys = ["order_id"], values = [1042]
Output:
{"order_id":1042}Worked solution and explanation
This is a header-to-row pairing dressed up as a CSV loader, and the only thing it really probes is what happens when a column name repeats. Anyone can pair two lists by position. What separates candidates is resisting the defensive instinct to guard the insert with if column not in record. It feels careful, and here it is exactly backwards: on keys = ['sku', 'qty', 'sku'] with values = ['A100', 5, 'B200'] it keeps 'A100' when the row says 'B200'. Every record with a repeated column then loads stale data, and nothing errors to tell you.
Getting to the answer
Step 1: Pair each column with its cell by position
The lists are parallel: the i-th header names the i-th cell. Walk them together with zip(keys, values) rather than indexing two lists with one counter, so the pairing is explicit and there is no index to get wrong.
Step 2: Let a later column overwrite an earlier one
Plain assignment, record[column] = value, already gives you last-write-wins: the second 'sku' replaces the first. The correct answer here is the one with no extra logic, and the bug only appears if you add a membership check.
Step 3: Let the empty header fall out naturally
With keys = [] the loop body never runs and you return {}. There is nothing to special-case, so no guard clause is needed.
def dict_from_lists(keys: list, values: list) -> dict:
record = {}
for column, value in zip(keys, values):
record[column] = value
return record- First value wins (wrong)
if column not in record: record[column] = valueskips the second 'sku', so the record holds 'A100', a cell the row has already superseded.- Last value wins (correct)
record[column] = valueon every pair lets the second 'sku' replace the first, so the record holds 'B200', the rightmost cell, as the export intends.
Common follow-up questions
- What if `keys` and `values` can differ in length? (Tests knowing that `zip` truncates silently and that `zip(keys, values, strict=True)` raises instead.)
- What if we need every value for a repeated column instead of only the last? (Tests switching to a dict of lists, for example with `setdefault(column, []).append(value)`.)
- How would you load a whole export of rows against one header? (Tests reusing the header across rows and yielding one record per row without rebuilding anything.)