如何高效迭代包含多层子条件数组的嵌套字典?
condition值? 我有一个包含嵌套sub_conditions数组的字典结构,每个子项里都有condition字段,我需要提取所有层级的condition值。
示例字典结构:
d = { 'condition': 'Approval expected.', 'sub_conditions': [ { 'condition': 'Approved Activities: {reading} {crafting}', 'sub_conditions': [ { 'condition': 'Field Areas: # of areas, dimensions - {start_date} {end_date} {email}', 'sub_conditions': [ { 'condition': 'Room Areas: # of rooms, dimensions - {start_date} {end_date} {email}', 'sub_conditions': [] } ] } ] } ] }
目前我用多层嵌套的for循环来遍历,但这种方法只能处理固定层级的结构,如果后续有更多层级就会失效:
for layer_one in d['sub_conditions']: print(layer_one['condition']) for layer_two in layer_one['sub_conditions']: print(layer_two['condition']) for layer_three in layer_two['sub_conditions']: print(layer_three['condition'])
输出是符合预期的,但扩展性太差:
Approved Activities: {reading} {crafting}
Field Areas: # of areas, dimensions - {start_date} {end_date} {email}
Room Areas: # of rooms, dimensions - {start_date} {end_date} {email}
请问有没有更通用、可扩展的处理方式?
针对这种可变深度的嵌套结构,最通用的方法是使用递归或者迭代式的深度优先/广度优先搜索,两种方法都能处理任意层级的嵌套,不用提前知道结构的深度。
方法1:递归遍历(最简洁直观)
递归的思路很简单:对于每个字典,先提取它的condition,然后再递归处理它的sub_conditions数组里的每个子项。
def extract_conditions(node): # 提取当前节点的condition yield node['condition'] # 递归处理所有子条件 for sub_node in node['sub_conditions']: yield from extract_conditions(sub_node) # 使用示例 d = {'condition': 'Approval expected.', 'sub_conditions': [ {'condition': 'Approved Activities: {reading} {crafting}', 'sub_conditions': [ {'condition': 'Field Areas: # of areas, dimensions - {start_date} {end_date} {email}', 'sub_conditions': [ {'condition': 'Room Areas: # of rooms, dimensions - {start_date} {end_date} {email}', 'sub_conditions': []}]}]}]} for cond in extract_conditions(d): print(cond)
运行结果会包含所有层级的condition,包括最顶层的:
Approval expected.
Approved Activities: {reading} {crafting}
Field Areas: # of areas, dimensions - {start_date} {end_date} {email}
Room Areas: # of rooms, dimensions - {start_date} {end_date} {email}
如果只需要子层级的condition(不需要最顶层的),可以直接从d['sub_conditions']开始遍历:
for sub_node in d['sub_conditions']: for cond in extract_conditions(sub_node): print(cond)
方法2:迭代式深度优先搜索(避免递归栈溢出)
如果嵌套层级非常深(比如超过Python默认的递归深度限制,默认是1000层),递归可能会抛出RecursionError,这时候可以用迭代的方式模拟深度优先搜索,用栈来保存待处理的节点:
def extract_conditions_iterative(start_nodes): stack = list(start_nodes) while stack: node = stack.pop() # 先添加当前节点的condition yield node['condition'] # 把子节点压入栈(反转顺序保证输出和递归一致) stack.extend(reversed(node['sub_conditions'])) # 使用示例,从sub_conditions开始 for cond in extract_conditions_iterative(d['sub_conditions']): print(cond)
这个方法的输出和你原来的多层循环完全一致,而且可以处理任意深度的嵌套。
方法3:迭代式广度优先搜索(按层级顺序输出)
如果你希望按照层级从上到下输出(先第一层子条件,再第二层,以此类推),可以用队列来实现广度优先搜索:
from collections import deque def extract_conditions_bfs(start_nodes): queue = deque(start_nodes) while queue: node = queue.popleft() yield node['condition'] queue.extend(node['sub_conditions']) # 使用示例 for cond in extract_conditions_bfs(d['sub_conditions']): print(cond)
输出顺序和深度优先一致,但如果结构更复杂、层级差异大的话,广度优先会先输出所有同层级的条件,再往下遍历更深的层级。
内容的提问来源于stack exchange,提问作者JarochoEngineer

