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
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 resultCommon follow-up questions
- What if lists inside the config should also be expanded into their elements? (Tests extending the isinstance check to descend into both dicts and lists.)
- How would you return each leaf's key path alongside its value? (Tests carrying the path as a list of keys down the recursion.)
- What if the nesting depth reaches 10,000 levels? (Tests rewriting the recursion as an explicit stack to dodge the recursion limit.)