简体   繁体   中英

Insert element in Nested Json using another dict python

I have json object and mapper like below,

Json Object:

{
    'App Builder': {
        'ID': '1',
        'children': [{
            'API Builder': {
                'ID': '2'
            }
        }, {
            'UI': {
                'ID': '3',
                'children': [{
                    'UI Builder': {
                        'ID': '4'
                    }
                }, {
                    'Template': {
                        'ID': '5',
                        'children': [{
                            'Angular': {
                                'ID': '6'
                            }
                        }, {
                            'React': {
                                'ID': '7'
                            }
                        }, {
                            'PHP': {
                                'ID': '8'
                            }
                        }]
                    }
                }]
            }
        }]
    }
}

Mapper:

{
    '1': ['create an app', 'create app for me', 'can you create an application?'],
    '2': ['create an app using API Buider', 'make an application using API Builder', 'create API Builder application'],
    '3': ['create an app using user interface', 'make an application using UI', 'create UI application'],
    '4': ['create an app using UI Buider', 'make an application using UI Builder', 'create UI Builder application'],
    '5': ['create an app using Template', 'make an application using Template', 'create Template application'],
    '6': ['create an app using Angular', 'make an application using Angular template', 'create Angular application'],
    '7': ['create an app using React', 'make an application using React template', 'create React application'],
    '8': ['create an app using PHP', 'make an application using PHP template', 'create PHP application']
}

Both object contains 'ID' using this I need to append values in original json object like below,

{
    "App Builder": {
        "ID": "1",
        "1": ["create an app", "create app for me", "can you create an application?"],

        "children": [{
            "API Builder": {
                "ID": "2",
                "2": ["create an app using API Buider", "make an application using API Builder", "create API Builder application"]

            }
        }, {
            "UI": {
                "ID": "3",
                "3": ["create an app using user interface", "make an application using UI", "create UI application"],

                "children": [{
                    "UI Builder": {
                        "ID": "4",
                        "4": ["create an app using UI Buider", "make an application using UI Builder", "create UI Builder application"]

                    }
                }, {
                    "Template": {
                        "ID": "5",
                        "5": ["create an app using Template", "make an application using Template", "create Template application"],
                        "children": [{
                            "Angular": {
                                "ID": "6",
                                "6": ["create an app using Angular", "make an application using Angular template", "create Angular application"]

                            }
                        }, {
                            "React": {
                                "ID": "7",
                                "7": ["create an app using React", "make an application using React template", "create React application"]

                            }
                        }, {
                            "PHP": {
                                "ID": "8",
                                "8": ["create an app using PHP", "make an application using PHP template", "create PHP application"]

                            }
                        }]
                    }
                }]
            }
        }]
    }
}

I tried to get path of my required json object using below.

json_path = {}
for intent in all_walks:
    ep = []
    temp = s
    i=0
    for val in intent.split('/'):
        if i==0:
            ep.append(val)
            temp = temp[val]
        else:
            temp = temp['children']
            ep.append('children')
            for item in temp:
                if val in item.keys():
                    ep.append(val)
                    temp = item[val]
        i+=1
        json_path[intent] = ep

print(json_path)

it gives me,

{'App Builder': ['App Builder'], 'App Builder/API Builder': ['App Builder', 'children', 'API Builder'], 'App Builder/UI': ['App Builder', 'children', 'UI'], 'App Builder/UI/UI Builder': ['App Builder', 'children', 'UI', 'children', 'UI Builder'], 'App Builder/UI/Template': ['App Builder', 'children', 'UI', 'children', 'Template'], 'App Builder/UI/Template/Angular': ['App Builder', 'children', 'UI', 'children', 'Template', 'children', 'Angular'], 'App Builder/UI/Template/React': ['App Builder', 'children', 'UI', 'children', 'Template', 'children', 'React'], 'App Builder/UI/Template/PHP': ['App Builder', 'children', 'UI', 'children', 'Template', 'children', 'PHP']}

Again I can't use this because children is an array.

How to solve this problem.

any help would be appreciable.

I have made a recursive function to set the mapped data:

data = {
    'App Builder': {
        'ID': '1',
        'children': [{
            'API Builder': {
                'ID': '2'
            }
        }, {
            'UI': {
                'ID': '3',
                'children': [{
                    'UI Builder': {
                        'ID': '4'
                    }
                }, {
                    'Template': {
                        'ID': '5',
                        'children': [{
                            'Angular': {
                                'ID': '6'
                            }
                        }, {
                            'React': {
                                'ID': '7'
                            }
                        }, {
                            'PHP': {
                                'ID': '8'
                            }
                        }]
                    }
                }]
            }
        }]
    }
}

mapper = {
    '1': ['create an app', 'create app for me', 'can you create an application?'],
    '2': ['create an app using API Buider', 'make an application using API Builder', 'create API Builder application'],
    '3': ['create an app using user interface', 'make an application using UI', 'create UI application'],
    '4': ['create an app using UI Buider', 'make an application using UI Builder', 'create UI Builder application'],
    '5': ['create an app using Template', 'make an application using Template', 'create Template application'],
    '6': ['create an app using Angular', 'make an application using Angular template', 'create Angular application'],
    '7': ['create an app using React', 'make an application using React template', 'create React application'],
    '8': ['create an app using PHP', 'make an application using PHP template', 'create PHP application']
}

def setDataFromNestedDict(data, dictKey):
    if isinstance(data, dict):
        if dictKey in data.keys():
            data[data[dictKey]] = mapper[data[dictKey]]
        for key, value in data.items():
            if isinstance(value, dict):
                setDataFromNestedDict(value, dictKey)
            elif isinstance(value, list):
                for item in value:
                    setDataFromNestedDict(item,dictKey)

    elif isinstance(data, list):
        for item in data:
            setDataFromNestedDict(item,dictKey)

setDataFromNestedDict(data, 'ID')
print(data)

output:

{'App Builder': {'1': ['create an app',
   'create app for me',
   'can you create an application?'],
  'ID': '1',
  'children': [{'API Builder': {'2': ['create an app using API Buider',
      'make an application using API Builder',
      'create API Builder application'],
     'ID': '2'}},
   {'UI': {'3': ['create an app using user interface',
      'make an application using UI',
      'create UI application'],
     'ID': '3',
     'children': [{'UI Builder': {'4': ['create an app using UI Buider',
         'make an application using UI Builder',
         'create UI Builder application'],
        'ID': '4'}},
      {'Template': {'5': ['create an app using Template',
         'make an application using Template',
         'create Template application'],
        'ID': '5',
        'children': [{'Angular': {'6': ['create an app using Angular',
            'make an application using Angular template',
            'create Angular application'],
           'ID': '6'}},
         {'React': {'7': ['create an app using React',
            'make an application using React template',
            'create React application'],
           'ID': '7'}},
         {'PHP': {'8': ['create an app using PHP',
            'make an application using PHP template',
            'create PHP application'],
           'ID': '8'}}]}}]}}]}}

You can use object_hook parameter of json.loads which is an optional function that will be called with the result of any object literal decoded (a dict). For example,

For the below JSON

sample_json = """{
    "App Builder": {
        "ID": "1",
        "children": [
            {
                "API Builder": {
                    "ID": "2"
                }
            },
            {
                "UI": {
                    "ID": "3",
                    "children": [
                        {
                            "UI Builder": {
                                "ID": "4"
                            }
                        },
                        {
                            "Template": {
                                "ID": "5",
                                "children": [
                                    {
                                        "Angular": {
                                            "ID": "6"
                                        }
                                    },
                                    {
                                        "React": {
                                            "ID": "7"
                                        }
                                    },
                                    {
                                        "PHP": {
                                            "ID": "8"
                                        }
                                    }
                                ]
                            }
                        }
                    ]
                }
            }
        ]
    }
}"""

And with the following Mapper,

mapper = {
    '1': ['create an app', 'create app for me', 'can you create an application?'],
    '2': ['create an app using API Buider', 'make an application using API Builder', 'create API Builder application'],
    '3': ['create an app using user interface', 'make an application using UI', 'create UI application'],
    '4': ['create an app using UI Buider', 'make an application using UI Builder', 'create UI Builder application'],
    '5': ['create an app using Template', 'make an application using Template', 'create Template application'],
    '6': ['create an app using Angular', 'make an application using Angular template', 'create Angular application'],
    '7': ['create an app using React', 'make an application using React template', 'create React application'],
    '8': ['create an app using PHP', 'make an application using PHP template', 'create PHP application']
}

You can implement a object_hook function like the below one

import json

def hook(obj):
    if 'ID' in obj:
        key = obj["ID"]
        obj.update({key: mapper[key]})
    return obj

data = json.loads(sample_json, object_hook=hook)
json = json.dumps(data, indent=4)
print(json)

will produce the following output

{
    "App Builder": {
        "ID": "1",
        "children": [
            {
                "API Builder": {
                    "ID": "2",
                    "2": [
                        "create an app using API Buider",
                        "make an application using API Builder",
                        "create API Builder application"
                    ]
                }
            },
            {
                "UI": {
                    "ID": "3",
                    "children": [
                        {
                            "UI Builder": {
                                "ID": "4",
                                "4": [
                                    "create an app using UI Buider",
                                    "make an application using UI Builder",
                                    "create UI Builder application"
                                ]
                            }
                        },
                        {
                            "Template": {
                                "ID": "5",
                                "children": [
                                    {
                                        "Angular": {
                                            "ID": "6",
                                            "6": [
                                                "create an app using Angular",
                                                "make an application using Angular template",
                                                "create Angular application"
                                            ]
                                        }
                                    },
                                    {
                                        "React": {
                                            "ID": "7",
                                            "7": [
                                                "create an app using React",
                                                "make an application using React template",
                                                "create React application"
                                            ]
                                        }
                                    },
                                    {
                                        "PHP": {
                                            "ID": "8",
                                            "8": [
                                                "create an app using PHP",
                                                "make an application using PHP template",
                                                "create PHP application"
                                            ]
                                        }
                                    }
                                ],
                                "5": [
                                    "create an app using Template",
                                    "make an application using Template",
                                    "create Template application"
                                ]
                            }
                        }
                    ],
                    "3": [
                        "create an app using user interface",
                        "make an application using UI",
                        "create UI application"
                    ]
                }
            }
        ],
        "1": [
            "create an app",
            "create app for me",
            "can you create an application?"
        ]
    }
}

You can use simple recursion:

data = {'App Builder': {'ID': '1', 'children': [{'API Builder': {'ID': '2'}}, {'UI': {'ID': '3', 'children': [{'UI Builder': {'ID': '4'}}, {'Template': {'ID': '5', 'children': [{'Angular': {'ID': '6'}}, {'React': {'ID': '7'}}, {'PHP': {'ID': '8'}}]}}]}}]}}
l = {'1': ['create an app', 'create app for me', 'can you create an application?'], '2': ['create an app using API Buider', 'make an application using API Builder', 'create API Builder application'], '3': ['create an app using user interface', 'make an application using UI', 'create UI application'], '4': ['create an app using UI Buider', 'make an application using UI Builder', 'create UI Builder application'], '5': ['create an app using Template', 'make an application using Template', 'create Template application'], '6': ['create an app using Angular', 'make an application using Angular template', 'create Angular application'], '7': ['create an app using React', 'make an application using React template', 'create React application'], '8': ['create an app using PHP', 'make an application using PHP template', 'create PHP application']}
def get_vals(d):
  if 'ID' not in d:
     return {a:get_vals(b) for a, b in d.items()}
  return {**d, d['ID']:l[d['ID']], 'children':[get_vals(i) for i in d.get('children', [])]}

import json
print(json.dumps(get_vals(data), indent=4))

Output:

{
"App Builder": {
    "ID": "1",
    "1": [
        "create an app",
        "create app for me",
        "can you create an application?"
    ],
    "children": [
        {
            "API Builder": {
                "ID": "2",
                "2": [
                    "create an app using API Buider",
                    "make an application using API Builder",
                    "create API Builder application"
                ],
                "children": []
            }
        },
        {
            "UI": {
                "ID": "3",
                "children": [
                    {
                        "UI Builder": {
                            "ID": "4",
                            "4": [
                                "create an app using UI Buider",
                                "make an application using UI Builder",
                                "create UI Builder application"
                            ],
                            "children": []
                        }
                    },
                    {
                        "Template": {
                            "ID": "5",
                            "children": [
                                {
                                    "Angular": {
                                        "ID": "6",
                                        "6": [
                                            "create an app using Angular",
                                            "make an application using Angular template",
                                            "create Angular application"
                                        ],
                                        "children": []
                                    }
                                },
                                {
                                    "React": {
                                        "ID": "7",
                                        "7": [
                                            "create an app using React",
                                            "make an application using React template",
                                            "create React application"
                                        ],
                                        "children": []
                                    }
                                },
                                {
                                    "PHP": {
                                        "ID": "8",
                                        "8": [
                                            "create an app using PHP",
                                            "make an application using PHP template",
                                            "create PHP application"
                                        ],
                                        "children": []
                                    }
                                }
                            ],
                            "5": [
                                "create an app using Template",
                                "make an application using Template",
                                "create Template application"
                            ]
                        }
                    }
                ],
                "3": [
                    "create an app using user interface",
                    "make an application using UI",
                    "create UI application"
                ]
            }
        }
    ],
}

My co-worker @Akshay pai suggested another impressive solution. The idea behind that is usage of call by reference through recursive call.

def restructure(tree_data):
    if tree_data is None:
        return tree_data
    root_element = list(tree_data.keys())[0]
    tree_data = tree_data[root_element]
    tree_data["utterance"] = intent_mapper[tree_data["ID"]]
    if "children" not in tree_data:
        return tree_data
    for child in tree_data["children"]:
        restructure(child)
restructure(tree_data)

O/P:

{
    "App Builder": {
        "ID": "1",
        "children": [
            {
                "API Builder": {
                    "ID": "2",
                    "utterance": [
                        "create an app using API Buider",
                        "make an application using API Builder",
                        "create API Builder application"
                    ]
                }
            },
            {
                "UI": {
                    "ID": "3",
                    "children": [
                        {
                            "UI Builder": {
                                "ID": "4",
                                "utterance": [
                                    "create an app using UI Buider",
                                    "make an application using UI Builder",
                                    "create UI Builder application"
                                ]
                            }
                        },
                        {
                            "Template": {
                                "ID": "5",
                                "children": [
                                    {
                                        "Angular": {
                                            "ID": "6",
                                            "utterance": [
                                                "create an app using Angular",
                                                "make an application using Angular template",
                                                "create Angular application"
                                            ]
                                        }
                                    },
                                    {
                                        "React": {
                                            "ID": "7",
                                            "utterance": [
                                                "create an app using React",
                                                "make an application using React template",
                                                "create React application"
                                            ]
                                        }
                                    },
                                    {
                                        "PHP": {
                                            "ID": "8",
                                            "utterance": [
                                                "create an app using PHP",
                                                "make an application using PHP template",
                                                "create PHP application"
                                            ]
                                        }
                                    }
                                ],
                                "utterance": [
                                    "create an app using Template",
                                    "make an application using Template",
                                    "create Template application"
                                ]
                            }
                        }
                    ],
                    "utterance": [
                        "create an app using user interface",
                        "make an application using UI",
                        "create UI application"
                    ]
                }
            }
        ],
        "utterance": [
            "create an app",
            "create app for me",
            "can you create an application?"
        ]
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM