Python:将带空格标识层级的字符串列表转为未知深度嵌套结构
I'm trying to convert a list of strings (where indentation with leading spaces indicates hierarchy depth) into a nested structure of unknown depth using Python. Here's my specific example:
Input List:
[ '[id]', '[first_name]', '[last_name]', '[addresses]', ' [[status]]', ' [[address]]', ' [[city]]', ' [[state]]', ' [[zip]]', ' [[numberOfYears]]', ' [[[status]]]', ' [[[[SUM]]]]', ' [[[[[SUBSUM]]]]]' ]Desired Output (note: adjusted to use arrays for
fieldsfor consistency — original desired output had some single-objectfieldswhich can't support multiple child nodes):[ {"name": "[id]", "fields": []}, {"name": "[first_name]", "fields": []}, {"name": "[last_name]", "fields": []}, {"name": "[addresses]", "fields": [ {"name": "[status]", "fields": []}, {"name": "[address]", "fields": []}, {"name": "[city]", "fields": []}, {"name": "[state]", "fields": []}, {"name": "[zip]", "fields": []}, {"name": "[numberOfYears]", "fields": [ {"name": "[status]", "fields": [ {"name": "[SUM]", "fields": [ {"name": "[SUBSUM]", "fields": []} ]} ]} ]} ]} ]
Solution Using a Stack to Track Hierarchy
The core of this problem is keeping track of the correct parent node as we move up and down the hierarchy. A stack is ideal here because it lets us easily "backtrack" to parent nodes when the indentation level decreases.
Here's a Python implementation that handles arbitrary nesting depth:
def indented_list_to_nested(input_list): result = [] stack = [] # Stores tuples of (current_node, current_indent_level) for item in input_list: # Calculate how deep this node is (number of leading spaces) indent_level = len(item) - len(item.lstrip()) # Clean up the string to get the node name node_name = item.strip() # Create the new node structure new_node = {"name": node_name, "fields": []} if not stack: # No parent nodes yet — this is a top-level node result.append(new_node) stack.append((new_node, indent_level)) else: # Pop nodes from the stack until we find the correct parent while stack and stack[-1][1] >= indent_level: stack.pop() # Attach the new node to its parent's fields stack[-1][0]["fields"].append(new_node) # Push the new node to the stack for future children stack.append((new_node, indent_level)) return result # Test with your input data input_data = [ '[id]', '[first_name]', '[last_name]', '[addresses]', ' [[status]]', ' [[address]]', ' [[city]]', ' [[state]]', ' [[zip]]', ' [[numberOfYears]]', ' [[[status]]]', ' [[[[SUM]]]]', ' [[[[[SUBSUM]]]]]' ] nested_output = indented_list_to_nested(input_data) # Print formatted output for readability import json print(json.dumps(nested_output, indent=4))
How It Works
- Indentation Level Calculation: For each string, we count the leading spaces to determine its position in the hierarchy.
- Node Creation: Every string becomes a node with a
name(cleaned of whitespace) and an emptyfieldsarray to hold child nodes. - Stack Management:
- If the stack is empty, we're dealing with a top-level node — add it to the result and push it to the stack.
- If the stack isn't empty, we pop nodes until we find a parent with a lower indent level (this ensures we're attaching the new node to the correct parent).
- We add the new node to the parent's
fieldsarray, then push the new node to the stack to track any future child nodes.
Key Note
Your original desired output used single objects for some fields values, but this would break if a parent has multiple child nodes. Using arrays for fields is the consistent, scalable approach that supports any number of children at any hierarchy level.
内容的提问来源于stack exchange,提问作者Ghassen

