One Step Behind

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

Domain
Python
Difficulty
medium
Seniority
L3

Problem

You're aligning a stream of sensor readings so each one can sit beside the reading that came just before it. Return a list the same length as the input, where each slot carries its predecessor's value.

What came before this row?

Example 1

Input:

values = [10,20,15,30,25]

Output:

[null,10,20,15,30]

Example 2

Input:

values = [5]

Output:

[null]

Worked solution and explanation

The real problem

Underneath the lag framing this is a boundary problem, not a shifting problem. Carrying each value into the next slot is the easy part; the tell is what you seed the output with and where its length comes from. The shortcut almost everyone reaches for seeds result = [None] and copies from index 1, which reads fine until an empty list arrives and you hand back [None] instead of []. That one phantom row breaks the same-length promise every downstream column-align step leans on.


Walk it

Step 1: Carry the previous value forward

Keep a single prev variable. Before you read each value, the answer for the current slot is whatever you saw last time, which starts as None. Append prev, then update it to the current value. The first append naturally lands None because nothing came before.

Step 2: Let the input drive the length

The output grows one slot per input element, so its length is the input's length by construction. That is the whole fix: never seed a slot the input did not ask for. Empty input walks zero times and returns an empty list; a single element appends exactly one None.


The solution

Carry the predecessor forward, one slot per input element
def lag(values):
    result = []
    prev = None
    for value in values:
        result.append(prev)
        prev = value
    return result

Length comes from the loop, so empty in gives empty out.

Seed-and-copy (breaks on empty)
result = [None] then loop range(1, len(values)). Correct on every non-empty input, but an empty list returns [None], a length-1 result where the contract demands length 0.
Carry-forward (length from input)
Start result = [] and append one slot per element. The length is whatever the input's length is, so the empty case falls out as [] with no special-casing.

Common follow-up questions