首页 > 解决方案 > 递归添加 subdict

问题描述

我正在使用 Python 中的一些严重嵌套的字典,并试图递归地更新它们。数据(代表 Nary 树)看起来像这样:

{
    "root": {
        "value": 1.0,
        "name": null,
        "children": [
            {
                "value": 0.5,
                "name": null,
                "children": [
                    {
                        "value": 0.5,
                        "name": null,
                        "children": []    
                    },
                    {
                        "value": 3.0,
                        "name": "B",
                        "children": []
                    }
                ]
            }
        ]
    }
}

字典的每一层都有一个值和名称键。我希望这两个键的每个实例(即在每个级别)都成为一个附加 subdict 的值(例如,名称为“text”),即数据需要看起来像:

{
    "root": {
        "text": {
            "value": 1.0,
            "name": null,
        },
        "children": [
            {
                "text": {
                    "value": 0.5,
                    "name": null,
                },
                "children": [
                    {
                        "text": {
                            "value": 0.5,
                            "name": null,
                        },
                        "children": []    
                    },
                    {
                        "text": {
                            "value": 3.0,
                            "name": "B",
                        },
                        "children": []
                    }
                ]
            }
        ]
    }
}

我敢肯定这很容易做到,但我似乎无法解决!我尝试了几种使用递归的不同方法,但遇到了很多错误。(如果使用 javascript 中的 JSON.parse 更容易做到这一点,那也很好。)任何帮助将不胜感激。以下极其错误的解决方案是我的第一次尝试,但由于它不完整,它显然不起作用;我不确定如何以这种递归方式在同一迭代中访问两个键并在同一迭代中更新字典。

def add_encapsulation(json_input, lookup_key1, lookup_key2):
    for key, val in json_input.items():
        updated_key = "text"
        subdict = dict()
        if key == lookup_key1:
            vals[key] = json_input["value"]
        elif key == lookup_key2:
            vals[key] = json_input["name"]
            # I can't access the two keys in the same iteration, so you can't add them 
            # to the subdict. Also, how can you add the subdict to the dict at the appropriate place? 
        else:
            add_encapsulation(v, lookup_key1, lookup_key2)

标签: pythonjsondictionaryrecursion

解决方案


root 和 children 下的键似乎遵循相同的模式(value, name, children),因此递归函数可能如下所示:


data = json.loads('''{
    "root": {
        "value": 1.0,
        "name": null,
        "children": [
            {
                "value": 0.5,
                "name": null,
                "children": [
                    {
                        "value": 0.5,
                        "name": null,
                        "children": []    
                    },
                    {
                        "value": 3.0,
                        "name": "B",
                        "children": []
                    }
                ]
            }
        ]
    }
}''')


def encapsulate(d):
    rv = {}
    value, name, children = d.values()
    rv['text'] = {'value': value, 'name': name}
    rv['children'] = [encapsulate(c) for c in children]

    return rv


print({'root': encapsulate(data['root'])})

输出:

{'root': {'text': {'value': 1.0, 'name': None}, 'children': [{'text': {'value': 0.5, 'name': None}, 'children': [{'text': {'value': 0.5, 'name': None}, 'children': []}, {'text': {'value': 3.0, 'name': 'B'}, 'children': []}]}]}}

推荐阅读