Traverse nested dictionary from depth and move to top
Asked Answered
S

1

0

I have below dictionary (generated from a report, so the structure can change). I need to go to the depth of the dictionary, find the id which in this case is 'id': u'ef3c8cf1-0987-4e56-a6d5-763c42be1f75', (there can be more than 1), delete that id and then move to one level up and repeat the same till I get to the top id which I finally delete. Since there is a dependency, I need to delete the orphan id first and then move to the top.

Any help is appreciable. If any other file/information is needed, please let me know.

{ 
'id': u'4c31d813-a989-47dd-b01b-9a27b8db2dfc',                                                                                                                      
'snapshots': 
    [
        {
            'id': u'3ddc7ddd-02ca-4669-a0cb-fb0d56a4a6f5', 
            'volumes': 
                [
                    {  
                        'id': u'5488de90-50dc-4d72-a6aa-c995422fa179', 
                        'snapshots': [], 
                        'snapshot_id': u'3ddc7ddd-02ca-4669-a0cb-fb0d56a4a6f5'
                    }, 
                    {
                        'id': u'e566645f-4fb3-4778-be67-447a5bdd678d', 
                        'snapshots': 
                            [
                                { 
                                    'id': u'd637f6ea-4a41-448c-874f-ffe624ddc597', 
                                    'volumes': 
                                        [
                                            { 
                                                'id': u'ef3c8cf1-0987-4e56-a6d5-763c42be1f75', 
                                                'snapshots': [], 
                                                'snapshot_id': u'd637f6ea-4a41-448c-874f-ffe624ddc597'
                                            }
                                        ]
                                }
                            ], 
                        'snapshot_id': u'3ddc7ddd-02ca-4669-a0cb-fb0d56a4a6f5'}, 
                    {
                        'id': u'196483ee-4f21-4d83-8e15-8caea532b2ab', 
                        'snapshots': [], 
                        'snapshot_id': u'3ddc7ddd-02ca-4669-a0cb-fb0d56a4a6f5'
                    }
                ]
        }
    ], 
'snapshot_id': None
}

Python code

oh=openstack_helper.OpenstackHelper()

def get_objects(item):
    items=None
    if item == 'stacks':
        items=oh.get_stacks()
    if item == 'volumes':
        items=oh.get_volumes()
    if item == 'snapshots':
        items=oh.get_snapshots()
    return items


def dep_graph(volumes,snapshots,snapshot_id=None):
    vol_list=[]

    for volume in volumes:
        if volume.snapshot_id == snapshot_id:
            info={'id':volume.id,'snapshot_id':volume.snapshot_id,'snapshots':[],
                  }
            vol_list.append(info)
    for snapshot in snapshots:
        for volume in vol_list:
            snap_list=[]
            if snapshot.volume_id == volume['id']:
               info={'id':snapshot.id, 'volumes':[]}
               info['volumes'].extend(dep_graph(volumes,snapshots,snapshot.id))
               volume['snapshots'].append(info)
    return vol_list

if __name__ == '__main__':

    volumes = get_objects('volumes')
    snapshots = get_objects('snapshots')
    output = dep_graph(volumes, snapshots)
    print output
Southey answered 1/6, 2018 at 11:58 Comment(4)
Exactly which part of this are you stuck on?Odeliaodelinda
I honestly dont have a clue how to get to the depth of this dictionary(I found on stackoverflow how to get the depth) and then delete that id itself and move to the top.Southey
Is this the only possible way you are getting these values or some other pattern as well? 'snapshot' value has it's own id, then for that id, 'volume' has it's own.Crapulent
Not the only possible way. But this is what I got for now. And true that snapshot has its own id for which if there is a volume, it will have its own id.Southey
C
3

Here is the solution I propose:

def remove_id(data):
    if isinstance(data, List):
        return [remove_id(sub_data) for sub_data in data]

    if isinstance(data, Dict):
        return {key: remove_id(value) for key, value in data.items()
                if key != 'id'}

    return data

And the result:

{'snapshot_id': None,
 'snapshots': [{'volumes': [{'snapshot_id': '3ddc7ddd-02ca-4669-a0cb-fb0d56a4a6f5',
                             'snapshots': []},
                            {'snapshot_id': '3ddc7ddd-02ca-4669-a0cb-fb0d56a4a6f5',
                             'snapshots': [{'volumes': [{'snapshot_id': 'd637f6ea-4a41-448c-874f-ffe624ddc597',
                                                         'snapshots': []}]}]},
                            {'snapshot_id': '3ddc7ddd-02ca-4669-a0cb-fb0d56a4a6f5',
                             'snapshots': []}]}]}
Cliffhanger answered 1/6, 2018 at 12:11 Comment(2)
Your data is a kind of tree. I am looking at every node of the tree. If the node is a dictionnary and contains 'id', I delete it. Then I recursively call the function to all children of the node.Cliffhanger
I edited my code : it is far better to test id key in the dict comprehension than to delete it from initial dictionnaryCliffhanger

© 2022 - 2024 — McMap. All rights reserved.