Extract Leaf Values

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
L4

Problem

A service's runtime configuration arrives as a nested dict config where each value is either a subsection (another dict) or a plain setting value at the bottom. Return every plain setting value in one flat list, ordered by where it sits: read each dict's keys top to bottom, and a subsection's values come out before the values of any sibling keys that follow it.

The tree has leaves. Pluck them.

Example 1

Input:

config = {"a":1,"b":{"c":2,"d":3}}

Output:

[1,2,3]

Example 2

Input:

config = {}

Output:

[]

Worked solution and explanation

What this really is

Strip off the config-export costume and this is a depth-first walk of a tree, where the only question that matters at each node is 'container or leaf?'. Anything that is a dict is a road to keep driving down; anything else is a destination to record. Candidates who reach for isinstance(value, dict) as the fork get it instantly. The ones who stumble try to special-case nesting levels or flatten with a fixed stack of loops, and they break the moment a subsection nests one level deeper than they planned for.


Break down the requirements

Step 1: Visit each value

For each value in the dict, decide whether it is itself a dict (keep descending) or a plain value (collect it).

Step 2: Descend into subsections

When a value is a dict, recursively extract its leaves and append them in order before moving to the next sibling key. This is what makes a subsection's values land before any keys that follow it.

Step 3: Collect non-dict values

Any value that is not a dict is a leaf and is appended straight to the result list.


The solution

Recursive walk collecting non-dict values
def leaf_values(config):
    result = []
    for key in config:
        value = config[key]
        if isinstance(value, dict):
            for leaf in leaf_values(value):
                result.append(leaf)
        else:
            result.append(value)
    return result

Common follow-up questions