Home > Net >  How to iterate through a nested dictionary with varying depth, and make a copy with value representi
How to iterate through a nested dictionary with varying depth, and make a copy with value representi

Time:09-16

I have a dictionary

 {'n11' : 
        {'n12a':
               {'n13a' : 10 , 'n13b' : "some text"},
         'n12b':
                {'n13c' : 
                          {'n14a': 40}
                }
         },
   'n21': 
         {'n22a' : 20 }
 }

And I want to iterate through the dictionary until I reach a value which is not a dictionary, and replace it with the "full path" to that value.

 {'n11' : 
        {'n12a':
               {'n13a' : 'n11_n12a_n13a' , 'n13b' : 'n11_n12a_n13b'},
         'n12b':
                {'n13c' : 
                          {'n14a': 'n11_n12b_n13c_n14a'}
                }
         },
   'n21': 
         {'n22a' : 'n21_n22a' }
 }

I know how to iterate through a nested dictionary with the following function, but I don't understand how to copy the same structure but with the updated value.

 def myprint(d,path=[]):
    for k, v in d.items():
        if isinstance(v, dict):
            path.append(k)
            myprint(v,path)
        else:
            print('_'.join(path))

  output:
  'n11_n12a_n13a'
  'n11_n12a_n13b'
  'n11_n12b_n13c_n14a'
  'n21_n22a'

But how do I get it into another dictionary?

CodePudding user response:

The most efficient way to do this would be using the same recursive function to not generate excess performance overhead. To copy the dictionary you can use copy.deepcopy() and then take that copy through the function, but replace the values instead of just printing the path:

import copy


data = {'n11': {'n12a': {'n13a': 10, 'n13b': "some text"}, 'n12b': {'n13c': {'n14a': 40}}}, 'n21': {'n22a': 20}}


def myreplace(d, path=[]):
for k, v in d.items():
    if isinstance(v, dict):
        myreplace(v, path   [k])
    else:
        print('_'.join(path   [k]))
        d[k] = '_'.join(path   [k])
return d


copy_of_data = copy.deepcopy(data)
copy_of_data = myreplace(copy_of_data)
print(data)
print(copy_of_data)

I had to modify the original function slightly to get it working.

  • Related