I have to work with a nested dictionary filled with numbers in python 'my_dict', and a list that specifies the subkeys 'keys 'that have to be deleted:
keys=[1,9]
my_dict={1:{1:a, 2:b}, 2:{1:c, 3:d, 9:e}}
I want to have two outcomes:
Delete all subkeys their values if they are in keys, e.g.
new_dict={1:{2:b}, 2:{3:d}}
Or Delete all subkeys their values if they are not in keys, e.g.
new_dict:{1:{1:a}, 2:{1:c,9:e}}
I have tried:
new_list = {outer_k: {inner_k: inner_v for inner_k, inner_v in outer_v.items()-{1,9}} for outer_k, outer_v in my_dict.items()}
It gives me back the same dict without deletion of the elements, same for the second szenario
new_list = {outer_k: {inner_k: inner_v for inner_k, inner_v in outer_v.items()&{1,9}} for outer_k, outer_v in my_dict.items()}
I have also tried:
for key, value in my_dict.items():
for key1, value1 in value.items():
for key1 in keys:
try:
del dict[key1]
except KeyError:
pass
This gives me the error:
TypeError: 'type' object does not support item deletion
I would be glad if anyone knows of a neat solution for this!
CodePudding user response:
Using dict comprehension:
new_dict = {k_out : {k_in : v_in for k_in, v_in in v_out.items() if k_in in keys} for k_out,v_out in my_dict.items()}
CodePudding user response:
The error TypeError: 'type' object does not support item deletion
stems from
for key, value in my_dict.items(): for key1, value1 in value.items(): for key1 in keys: try: del dict[key1] # this is the build in, not your instance # fix: del my_dict[key1] except KeyError: pass
As for the comprehensions - they look rather long ....
keys = [1,9]
my_dict = {1:{1:"a", 2:"b"}, 2:{1:"c", 3:"d", 9:"e"}}
# delete top levels
# for unwanted_key in keys:
# try:
# del my_dict[unwanted_key]
# except KeyError:
# pass
# delete inside sub levels
for unwanted_key in keys:
for inner_key in my_dict:
try:
del my_dict[inner_key][unwanted_key]
except KeyError:
pass
print( my_dict)
Results in
# {2: {3: 'd'}} # if you do top level and sub level
{1: {2: 'b'}, 2: {3: 'd'}} # if you only do sub levels
The try: ... except: ...
follows "Ask forgiveness not permission" - explain
CodePudding user response:
For your example , i recreated the data to runnable, however deleting directly from the dict you' re iterating on will throw an error , you can do it by creating a copy of a dictionary where will your result will be stored
keys=[1,9]
my_dict={1:{1:"a", 2:"b"}, 2:{1:"c", 3:"d", 9:"e"}}
my_dict
new_dict1=my_dict.copy()
for key, value in my_dict.items():
if key1 in value.keys() and key1 in keys:
# delete subkeys and their sub values
del new_dict1[key][key1]
CodePudding user response:
You can modify my_dict in situ like this:
keys = [1, 9]
my_dict = {1: {1: 'a', 2: 'b'}, 2: {1: 'c', 3: 'd', 9: 'e'}}
for v in my_dict.values():
for k in keys:
if k in v:
del v[k]
print(my_dict)
Output:
{1: {2: 'b'}, 2: {3: 'd'}}