Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to iterate through a nested dictionary with varying depth, and make a copy with value representing the path?

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?

like image 392
Kspr Avatar asked Oct 20 '25 14:10

Kspr


1 Answers

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.

like image 76
LTJ Avatar answered Oct 23 '25 02:10

LTJ



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!