1

I have a dict like this:

     d={
         'McAfee': {'DatDate': '123','DatVersion': '456'},
         'AntiVirus': {'AVName': ['Mac Defender', 'Windows Defender'],'AVVersion': ['262144', '393472']}
       }

Now I want to change the key of d and change the value's key of d too according to this mapping:

mapping_table = {"McAfee":'Mc_table','AntiVirus':'An_table'}

mapping_coulmn = {'DatDate':"Dc_column",'AVName':'Av_column','DatVersion':'Da_column','AVVersion':'AVV_column'}

The output should like:

 d={
    'Mc_table': {'Dc_column': '123','Da_column': '456'},
    'An_table': {'Av_column': ['Mac Defender', 'Windows Defender'],'AVV_column': ['262144', '393472']}
    }

What I tired is:

for key in d:
    if key in mapping_table:
        new_key = mapping_table[key]
        d1[new_key]=d.pop(key)
        
print(d)

It returns an error:

RuntimeError: dictionary keys changed during iteration

Any friend can help?Thank you so much!

William
  • 3,724
  • 9
  • 43
  • 76
  • Do you have to modify the dictionary in place instead of returning a new dictionary? – Barmar May 03 '21 at 18:41
  • I have no idea who edited this question and says it is duplicate, it is similar but not duplicate at all,I ask the person who edited my question to remove the duplicate tag! – William May 03 '21 at 18:51
  • Why isn't it a duplicate? `d.pop(key)` deletes from the dictionary. The other question explains how to delete from a dictionary while looping over it. – Barmar May 03 '21 at 18:53
  • In that question,the person wanted to del the key ,but I want to replace key and my dict structure is nested his is not. – William May 03 '21 at 19:06
  • There's no way to replace keys directly. All you can do is delete the old key and add a new key, which is what you're doing. But you can't modify keys while iterating. The other question provides the solution. – Barmar May 03 '21 at 19:08
  • Thank you for letting me know this! – William May 03 '21 at 19:19

1 Answers1

2
d = {
    mapping_table.get(k, k): {
        mapping_column.get(kk, kk): vv for kk, vv in v.items()
    }
    for k, v in d.items()
}
print(d)

Prints:

{'Mc_table': {'Dc_column': '123', 'Da_column': '456'}, 
 'An_table': {'Av_column': ['Mac Defender', 'Windows Defender'], 
              'AVV_column': ['262144', '393472']}}
Andrej Kesely
  • 168,389
  • 15
  • 48
  • 91
  • Thank you so much for you answer,bu can you add some explain about this line:vv for kk, vv in v.items() – William May 03 '21 at 19:20
  • @William `mapping_column.get(kk, kk): vv for kk, vv in v.items()` This line will iterate over every key, value in the dictionary, then tries to apply the mapping on key with `mapping_column.get(kk, kk)` (I use .`get()`, because if the value is not found in the mapping, the original key is returned - instead of an error) – Andrej Kesely May 03 '21 at 19:24
  • How can you iterate or loop such big logic only use 1 line? Please teach me!!For me,the first thing in my mind I will use something like for key in mapping_column:....but you just use 1 line!!! – William May 03 '21 at 19:26
  • @William Python has concept of dictionary comprehension (for lists, sets too). It's really useful to learn them. https://stackoverflow.com/questions/14507591/python-dictionary-comprehension – Andrej Kesely May 03 '21 at 19:28
  • Can you let me know,what is this line mean:vv for kk, vv in v.items(),is it same as for vv in kk or something else?! – William May 03 '21 at 19:28