The Chunked Reader

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
Asked in
Athenahealth

Problem

A batch shipper can only send chunk_size log lines per request, so a run of lines has to be split into successive batches before it goes out. Split lines into batches of at most chunk_size in their original order, and return the batches as a list of lists.

Too big for one payload. Ship it in pieces.

Example

Input:

lines = ["a","b","c","d","e"], chunk_size = 2

Output:

[["a","b"],["c","d"],["e"]]

Worked solution and explanation

How this problem really reads

Strip the costume and this is fixed-size batching with a ragged tail. Everyone can chop a list into pieces; what separates candidates is the last partial batch and not confusing indices with slices. The trap: reach for range(0, len(lines), chunk_size) and you hand back a list of integers instead of a list of lines, or special-case the tail by hand and you drop or duplicate the final element. The move is to stride the read position by chunk_size and let slicing clamp the last batch for you, producing one batch at a time so the batching logic stays reusable for a streaming caller even though this entrypoint materializes the result.


Break down the requirements

Step 1: Use a position pointer starting at 0

Track your current read position in the list. This replaces any need to mutate the input.

Step 2: Yield slices of chunk_size

On each iteration, yield lines[pos:pos + chunk_size]. Python slicing handles the case where fewer than chunk_size elements remain, so the ragged tail comes out for free.

Step 3: Advance the pointer

Increment pos by chunk_size after each yield. The loop ends when pos reaches or passes the list length, which is also how an empty input yields nothing.

Step 4: Materialize the batches into the returned list

Drive the generator from the entrypoint and collect its batches with list(...), returning a list of lists. The generator stays lazy; only the final return materializes.


The solution

Lazy generator, materialized into a list of lists
def chunked_read(lines: list, chunk_size: int):
    def _batches():
        pos = 0
        while pos < len(lines):
            yield lines[pos:pos + chunk_size]
            pos += chunk_size
    return list(_batches())

Common follow-up questions