You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于字典构建树形结构的递归实现问题求助

递归构建树形结构问题

给定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)

代码说明

  1. 核心递归逻辑:build_tree函数负责根据节点的键和数据创建Tree实例,当节点是object类型且存在properties时,遍历所有属性递归构建子节点并添加到当前节点。
  2. 顶层处理:直接获取输入字典的唯一顶层键值对,作为树形结构的根节点开始构建,无需额外的"root"节点(符合期望输出)。
  3. 辅助打印函数:print_tree通过缩进层级清晰展示树形结构,验证结果是否符合预期。

运行输出

PaymentCoverageRequestResource
    paymentCoverageRequestId
    payee
    instructedAmount
        amount
        currency
    accountId

内容的提问来源于stack exchange,提问作者Moh Za

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 03:44:52