0

I have a list

list_x = ['8', '4', '5', '6', '1']

and a dictionary

dict_1 = {'0': {'ID=3': 1, 'ID=7': 1},
 '1': {'ID=7': 2, 'ID=6': 2},
 '2': {'ID=7': 3, 'ID=5': 1},
 '3': {'ID=7': 2, 'ID=1': 1},
 '4': {'ID=3': 3, 'ID=5': 1, 'ID=4': 1},
 '5': {'ID=5': 1, 'ID=2': 3, 'ID=4': 2, 'ID=7': 1, 'ID=8': 1},
 '6': {'ID=0': 5, 'ID=3': 7, 'ID=1': 1},
 '7': {'ID=1': 1, 'ID=8': 1, 'ID=7': 1},
 '8': {'ID=6': 2, 'ID=0': 2, 'ID=2': 2}}

and I want to create a new dictionary dict_2 in which all items of dict_1 are stored that have a key that exists in list_x. How can I do that? I had trouble doing it with two nested for loops since I could access the keys but I could not copy the entire item.

lonyen11
  • 91
  • 11

4 Answers4

2

Try something like this

list_x = ['8', '4', '5', '6', '1']


dict_1 = {'0': {'ID=3': 1, 'ID=7': 1},
 '1': {'ID=7': 2, 'ID=6': 2},
 '2': {'ID=7': 3, 'ID=5': 1},
 '3': {'ID=7': 2, 'ID=1': 1},
 '4': {'ID=3': 3, 'ID=5': 1, 'ID=4': 1},
 '5': {'ID=5': 1, 'ID=2': 3, 'ID=4': 2, 'ID=7': 1, 'ID=8': 1},
 '6': {'ID=0': 5, 'ID=3': 7, 'ID=1': 1},
 '7': {'ID=1': 1, 'ID=8': 1, 'ID=7': 1},
 '8': {'ID=6': 2, 'ID=0': 2, 'ID=2': 2}}
d={k:dict_1.get(k).copy() for k in list_x if k in dict_1}
print(d)
  • @metapod, thanks. Added the control statement –  Aug 12 '21 at 15:38
  • If any value from ```dict_1``` is changed, it will be changed in ```dict_2```too ! You should get the nested dict by ```copy```: ```k:dict_1.get(k).copy()``` – Metapod Aug 12 '21 at 15:43
2

You can use operator.itemgetter for this pretty easily:

itemgetter(*list_x)(dict_1)

All code below:

from operator import itemgetter

list_x = ['8', '4', '5', '6', '1']
dict_1 = {'0': {'ID=3': 1, 'ID=7': 1},
 '1': {'ID=7': 2, 'ID=6': 2},
 '2': {'ID=7': 3, 'ID=5': 1},
 '3': {'ID=7': 2, 'ID=1': 1},
 '4': {'ID=3': 3, 'ID=5': 1, 'ID=4': 1},
 '5': {'ID=5': 1, 'ID=2': 3, 'ID=4': 2, 'ID=7': 1, 'ID=8': 1},
 '6': {'ID=0': 5, 'ID=3': 7, 'ID=1': 1},
 '7': {'ID=1': 1, 'ID=8': 1, 'ID=7': 1},
 '8': {'ID=6': 2, 'ID=0': 2, 'ID=2': 2}}
 
print(dict(zip(list_x, (itemgetter(*list_x)(dict_1)))))

{'8': {'ID=6': 2, 'ID=0': 2, 'ID=2': 2},
 '4': {'ID=3': 3, 'ID=5': 1, 'ID=4': 1},
 '5': {'ID=5': 1, 'ID=2': 3, 'ID=4': 2, 'ID=7': 1, 'ID=8': 1},
 '6': {'ID=0': 5, 'ID=3': 7, 'ID=1': 1},
 '1': {'ID=7': 2, 'ID=6': 2}}
Jab
  • 26,853
  • 21
  • 75
  • 114
0

The simple way is to use a dictionary comprehension, as so:

dict_2 = {k: v for k, v in dict_1.items() if k in list_x}

A note should be made, however, on the linking of the two dicts since they are collections which contain mutable items. If you want a completely separate result (when one changes the other stays the same) you can use deepcopy from the copy module:

from copy import deepcopy

list_x = ['8', '4', '5', '6', '1']

dict_1 = {'0': {'ID=3': 1, 'ID=7': 1},
 '1': {'ID=7': 2, 'ID=6': 2},
 '2': {'ID=7': 3, 'ID=5': 1},
 '3': {'ID=7': 2, 'ID=1': 1},
 '4': {'ID=3': 3, 'ID=5': 1, 'ID=4': 1},
 '5': {'ID=5': 1, 'ID=2': 3, 'ID=4': 2, 'ID=7': 1, 'ID=8': 1},
 '6': {'ID=0': 5, 'ID=3': 7, 'ID=1': 1},
 '7': {'ID=1': 1, 'ID=8': 1, 'ID=7': 1},
 '8': {'ID=6': 2, 'ID=0': 2, 'ID=2': 2}}

dict_2 = {k: v for k, v in deepcopy(dict_1).items() if k in list_x}

Now when doing an assignment such as dict_1['4']['ID=3'] = 1000, dict_2 will not be changed.

ChrisOram
  • 1,254
  • 1
  • 5
  • 17
0

try this:

dict_1 = {'0': {'ID=3': 1, 'ID=7': 1},
 '1': {'ID=7': 2, 'ID=6': 2},
 '2': {'ID=7': 3, 'ID=5': 1},
 '3': {'ID=7': 2, 'ID=1': 1},
 '4': {'ID=3': 3, 'ID=5': 1, 'ID=4': 1},
 '5': {'ID=5': 1, 'ID=2': 3, 'ID=4': 2, 'ID=7': 1, 'ID=8': 1},
 '6': {'ID=0': 5, 'ID=3': 7, 'ID=1': 1},
 '7': {'ID=1': 1, 'ID=8': 1, 'ID=7': 1},
 '8': {'ID=6': 2, 'ID=0': 2, 'ID=2': 2}}
 

list_x = ['8', '4', '5', '6', '1']
 
dict_2 = {}
for key, value in dict_1.items():
    if key in list_x:
        dict_2[key] = dict_1[key].copy()
         
         
print(dict_2)

Verify the above output.

See how to iterate dictionary items from here , here and here

To understand why copy() is used, see this post.

y_159
  • 458
  • 3
  • 15
  • 1
    As dicts are mutable, you should use ```copy```: ```dict_2[key] = dict_1[key].copy()```. Otherwise, changing ```dict_1``` will change ```dict_2``` too – Metapod Aug 12 '21 at 15:45
  • not in the above answer. you can verify it. – y_159 Aug 12 '21 at 15:48
  • I did: ```list_x = ['1']; dict_1['1']['ID=6'] = 456 ;print(dict_2); >> {'1': {'ID=7': 2, 'ID=6': 456}} ``` Because ```dict_1[X]``` is a dict. (I didn't mention the part with your algorithm, too lazy :) But it's of course done before the re-assignation) – Metapod Aug 12 '21 at 15:50