如何将层次结构字典转换为标识文本和节点的格式?

问题描述

我是python的新手,我一直在寻找一种使用一些代码将下面的字典转换为下面概述的格式的方法。

{'Parent 1': {'Child 1': {Grandchild 1: {},'Grandchild 2: {}},'Child 2': {}} Parent 2: {}}

然后将其转换为:

{
    'text': "Parent 1",'nodes': [
        {
            'text': "Child 1",'nodes': [
                {
                    'text': "Grandchild 1"
                },{
                    'text': "Grandchild 2"
                }
            ]
        },{
            'text': "Child 2"
        }
    ]
},{
    'text': "Parent 2"
}

解决方法

也许我不应该这么简单,但是我会给你答案。实际上有两个。请学习这些内容,以便您学习。如果这是家庭作业或其他内容,请不要不从中学习而直接提交答案。

第一种方法是无需递归即可解决问题。您只需逐级跟踪问题,做您需要做的事情以读取原始数据结构并生成新结构:

data = {'Parent 1': {'Child 1': {'Grandchild 1': {},'Grandchild 2': {}},'Child 2': {}},'Parent 2': {}}

parent_nodes = []
for parent_text,parent_data in data.items():
    parent_entry = {'text': parent_text}
    child_nodes = []
    for child_text,child_data in parent_data.items():
        child_entry = { 'text': child_text }
        grandchild_nodes = []
        for grandchild_text,grandchild_data in child_data.items():
            grandchild_entry = { 'text': grandchild_text }
            grandchild_nodes.append(grandchild_entry)
        if len(grandchild_nodes):
            child_entry['nodes'] = grandchild_nodes
        child_nodes.append(child_entry)
    if len(child_nodes):
        parent_entry['nodes'] = child_nodes
    parent_nodes.append(parent_entry)

print(json.dumps(parent_nodes,indent=4))

当您成为一名更好的程序员时,您将学习识别模式,这些模式将使您能够减少代码的大小并使代码更通用。在这种情况下,您可能会意识到此问题是关于具有遵循同一模式的多个级别的数据结构的。您应该能够编写不仅可以处理三个级别,而且可以处理4、5或100个级别的代码。

执行此操作的方法是使用递归。您认识到需要先处理较低级别的内容,然后才能完成较高级别的处理。在处理较低级别时,您会再次识别相同的事物,因此您首先要再次处理较低级别。这是递归。以下代码也可以实现您想要的功能,但是具有递归功能:

data = {'Parent 1': {'Child 1': {'Grandchild 1': {},'Parent 2': {}}

def do_one_level(data):
    nodes = []
    for text,entry in data.items():
        node = { 'text': text }
        subnode = do_one_level(entry)
        if len(subnode):
            node['nodes'] = subnode
        nodes.append(node)
    return nodes

parent_nodes = do_one_level(data)
print(json.dumps(parent_nodes,indent=4))

请注意,do_one_level()函数会自行调用。这是递归。请记住,第二个版本“更好”的原因不仅在于它的代码更少,而且更重要的是它可以处理输入数据结构中的任何数量的级别。

两个版本产生相同的输出:

[
    {
        "text": "Parent 1","nodes": [
            {
                "text": "Child 1","nodes": [
                    {
                        "text": "Grandchild 1"
                    },{
                        "text": "Grandchild 2"
                    }
                ]
            },{
                "text": "Child 2"
            }
        ]
    },{
        "text": "Parent 2"
    }
]
,

请尝试以下代码。用modify(input)

称呼它

代码

def modify(input):
    return [{"text":key,"nodes":modify(value) if isinstance(value,dict) else value} if value else {"text":key} for key,value in input.items()]
    

输入

input={'Parent 1': {'Child 1': {'Grandchild 1': {},'Parent 2': {}}

输出

[
  {
    "text": "Parent 1","nodes": [
      {
        "text": "Child 1","nodes": [
          {
            "text": "Grandchild 1"
          },{
            "text": "Grandchild 2"
          }
        ]
      },{
        "text": "Child 2"
      }
    ]
  },{
    "text": "Parent 2"
  }
]

注意:这使用递归

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...