基于字典构建树形结构的递归实现问题求助
递归构建树形结构问题
给定Tree类定义:
class Tree(): def __init__(self, data) -> None: self.data = data self.children = [] def addChildren(self, child): self.children.append(child)
需要将如下字典解析为树形结构,规则是当且仅当节点包含"type":"object"时,该节点为父节点,其子节点为"properties"中的所有键值对:
{ "PaymentCoverageRequestResource":{ "required":[ "accountId", "paymentCoverageRequestId" ], "type":"object", "properties":{ "paymentCoverageRequestId":{ "maxLength":35, "type":"string", "description":"Identification of the payment Coverage Request" }, "payee":{ "maxLength":70, "type":"string", "description":"The merchant where the card is accepted as information to the PSU." }, "instructedAmount":{ "type":"object", "properties":{ "amount":{ "maxLength":70, "type":"string", "description":"The merchant where the card is accepted as information to the PSU." }, "currency":{ "maxLength":3, "type":"string", "description":"The merchant where the card is accepted as information to the PSU." } } }, "accountId":{ "$ref":"another reference" } }, "description":"Payment coverage request structure.\nThe request must rely either on a cash account or a payment card.\nThe [instructedAmount] property is the payment account on wihich the request is processed. This amount must be positive.\nAmounts must always be set as positive values.\n", "example":"{\n \"paymentCoverageRequestId\" : \"MyCoverage123456\",\n \"instructedAmount\" : {\n \"amount\" : 12345.0,\n \"currency\" : \"EUR\"\n },\n \"accountId\" : {\n \"iban\" : \"YY13RDHN98392489481620896668799742\"\n }\n}", "x-definition-type":"Resources" } }
期望生成的树形结构:
PaymentCoverageRequestResource paymentCoverageRequestId payee instructedAmount amount currency accountId
原有递归代码存在逻辑问题,需要修正:
def parse_json(requestBody : dict): def parse_json_rec(tree : Tree, requestBody : dict): #something ? if len(requestBody) == 0: return tree (k, v), = requestBody.items() requestBody.pop(k) print(k) if v['type'] == 'object': # OR ARRAY parent_node = Tree(k) print(v) return parse_json_rec(tree.addChildren(parse_json_rec(parent_node, v), requestBody)) else: leaf_node = Tree(k) tree.addChildren(leaf_node) return parse_json_rec(tree, requestBody) pass root = Tree("root") return parse_json_rec(root, requestBody)
解决方案
修正后的递归代码
class Tree(): def __init__(self, data) -> None: self.data = data self.children = [] def addChildren(self, child): self.children.append(child) def parse_json(request_body: dict) -> Tree: # 递归核心函数:处理单个节点及其子节点 def build_tree(node_key: str, node_data: dict) -> Tree: current_node = Tree(node_key) # 判断当前节点是否为object类型,需要处理子节点 if node_data.get("type") == "object" and "properties" in node_data: # 遍历所有properties中的键值对,递归构建子节点 for prop_key, prop_data in node_data["properties"].items(): child_node = build_tree(prop_key, prop_data) current_node.addChildren(child_node) return current_node # 处理根字典的唯一顶层键值对 root_key, root_data = next(iter(request_body.items())) return build_tree(root_key, root_data) # 测试打印树形结构的辅助函数 def print_tree(node: Tree, indent: int = 0): print(" " * indent + node.data) for child in node.children: print_tree(child, indent + 1) # 调用示例 sample_dict = { "PaymentCoverageRequestResource":{ "required":["accountId","paymentCoverageRequestId"], "type":"object", "properties":{ "paymentCoverageRequestId":{"maxLength":35,"type":"string","description":"Identification of the payment Coverage Request"}, "payee":{"maxLength":70,"type":"string","description":"The merchant where the card is accepted as information to the PSU."}, "instructedAmount":{"type":"object","properties":{"amount":{"maxLength":70,"type":"string","description":"The merchant where the card is accepted as information to the PSU."},"currency":{"maxLength":3,"type":"string","description":"The merchant where the card is accepted as information to the PSU."}}}, "accountId":{"$ref":"another reference"} }, "description":"Payment coverage request structure.\nThe request must rely either on a cash account or a payment card.\nThe [instructedAmount] property is the payment account on wihich the request is processed. This amount must be positive.\nAmounts must always be set as positive values.\n", "example":"{\n \"paymentCoverageRequestId\" : \"MyCoverage123456\",\n \"instructedAmount\" : {\n \"amount\" : 12345.0,\n \"currency\" : \"EUR\"\n },\n \"accountId\" : {\n \"iban\" : \"YY13RDHN98392489481620896668799742\"\n }\n}", "x-definition-type":"Resources" } } result_tree = parse_json(sample_dict) print_tree(result_tree)
代码说明
- 核心递归逻辑:
build_tree函数负责根据节点的键和数据创建Tree实例,当节点是object类型且存在properties时,遍历所有属性递归构建子节点并添加到当前节点。 - 顶层处理:直接获取输入字典的唯一顶层键值对,作为树形结构的根节点开始构建,无需额外的"root"节点(符合期望输出)。
- 辅助打印函数:
print_tree通过缩进层级清晰展示树形结构,验证结果是否符合预期。
运行输出
PaymentCoverageRequestResource paymentCoverageRequestId payee instructedAmount amount currency accountId
内容的提问来源于stack exchange,提问作者Moh Za
相关产品推荐
相关产品推荐

