Coding Software Engineer
Hierarchical data often needs to be converted into a sequential form and later restored to its original layout. Common uses include preparing model inputs, deriving features, serializing data, and working with tree-like configuration objects.
A nested Python value in this task can use the following container types:
listtupledictEvery non-container value is guaranteed to be an integer.
You need to perform two operations:
Use one fixed visiting order so that results are predictable:
list from its first item through its last.tuple from its first item through its last.dict by iterating through its values in dictionary iteration order.You may rely on the insertion-order behavior of dictionaries in Python 3.7 and later.
structure = {
"left": [4, 6],
"right": {
"inner": [{"score": 8}],
"tail": 10,
},
}
# Flatten
flatten(structure) # [4, 6, 8, 10]
# Rebuild with the identical layout
unflatten([11, 13, 15, 17], structure)
# {
# "left": [11, 13],
# "right": {
# "inner": [{"score": 15}],
# "tail": 17,
# },
# }
structure = {"left": [4, 6], "right": {"inner": [{"score": 8}], "tail": 10}}[4,6, 8, 10]
The nested structure contains four integer leaves: 4, 6, 8, and 10.
The flat result follows the list and dictionary value order, and rebuilding assigns replacement values in that same sequence.
Create a flatten operation that receives a nested value and produces a list containing all integer leaves in the required traversal sequence.
The flattening operation accepts a nested Python object made from lists, tuples, dictionaries, and integer leaves, and returns list[int].
# Test 1: Dictionary containing lists and nested dictionaries
structure = {"west": [3, 5], "east": {"items": [{"id": 7}], "end": 9}}
assert flatten(structure) == [3, 5, 7, 9]
# Test 2: Interleaved tuple, list, and dictionary containers
structure = (2, [4, (6, 8)], {"value": 10})
assert flatten(structure) == [2, 4, 6, 8, 10]
# Test 3: One integer by itself
structure = 73
assert flatten(structure) == [73]
# Test 4: Containers with no contents
structure = {"items": [], "pair": (), "mapping": {}}
assert flatten(structure) == []
# Test 5: Several levels of nesting
structure = [[[[4]]], {"outer": {"middle": {"inner": 6}}}, (8,)]
assert flatten(structure) == [4, 6, 8]
# Test 6: Dictionary insertion order is significant
structure = {"alpha": 12, "beta": [14, 16], "gamma": 18}
assert flatten(structure) == [12, 14, 16, 18]
Each assertion reflects a depth-first visit, with dictionary values handled according to insertion order.
Implement the reverse-style operation. You are given:
flat_list: an ordered list of integers.structure: a nested value that supplies the target shape.Return a new object whose layout and container types exactly match structure, while replacing every integer leaf with the next entry from flat_list. Keep dictionary keys unchanged; only their leaf values may be replaced.
Raise ValueError whenever flat_list has either fewer or more integers than the template requires.
from typing import Any
def unflatten(flat_list: list[int], structure: Any) -> Any:
"""
Construct a new nested value whose layout matches `structure`.
Args:
flat_list: Integer replacements, read from left to right.
structure: The template whose containers define the returned shape.
Returns:
A newly created nested object preserving the template's container types
and organization.
Raises:
ValueError: Raised when flat_list does not contain exactly one integer
for every integer leaf in structure.
"""
pass
template = {
"front": [2, 4],
"back": {
"records": [{"count": 6}],
"last": 8,
},
}
result = unflatten([21, 23, 25, 27], template)
assert result == {
"front": [21, 23],
"back": {
"records": [{"count": 25}],
"last": 27,
},
}
The first two replacement values fill front, followed by the nested count leaf and then last.
# Test 1: Reconstruct a nested dictionary layout
template = {"front": [2, 4], "back": {"records": [{"count": 6}], "last": 8}}
expected = {"front": [21, 23], "back": {"records": [{"count": 25}], "last": 27}}
assert unflatten([21, 23, 25, 27], template) == expected
# Test 2: A tuple must remain a tuple
template = (3, [5, 7], {"value": 9})
result = unflatten([14, 16, 18, 20], template)
assert result == (14, [16, 18], {"value": 20})
assert isinstance(result, tuple)
# Test 3: Empty container nodes stay empty
template = {"items": [], "pair": (), "mapping": {}}
assert unflatten([], template) == {"items": [], "pair": (), "mapping": {}}
# Test 4: A template containing only one leaf
template = 250
assert unflatten([31], template) == 31
# Test 5: Not enough replacement values
template = [4, 6, 8]
try:
unflatten([12, 14], template)
assert False, "Expected ValueError"
except ValueError:
pass
# Test 6: Excess replacement values
template = {"only": 5}
try:
unflatten([19, 21], template)
assert False, "Expected ValueError"
except ValueError:
pass
# Test 7: A leaf-free template makes every supplied value excessive
template = {"items": [], "pair": (), "mapping": {}}
try:
unflatten([33], template)
assert False, "Expected ValueError"
except ValueError:
pass
These cases verify shape preservation, tuple retention, empty containers, and both length-mismatch failures.
structure = {"left": [4, 6], "right": {"inner": [{"score": 8}], "tail": 10}}[4,6, 8, 10]
The nested structure contains four integer leaves: 4, 6, 8, and 10.