My Problem: I have a nested dictionary that looks like this:
my_dict = {
'type_1' : {
'id1' : some_item,
'id2' : some_item_2,
},
'type_2' :{
'id3' : some_item3,
'id4' : some_item4,
}
}
I don't intent to add more nesting in those sub_dicts, so I think this should be fairly easy.
Now I want to get all to get all inner keys (everything that starts with 'id') in one list,
so that i get ['id1', 'id2', 'id3', 'id4]
The easy way would be to use two for loops, but I want it to be as concise as humanly possible.
My initial approach looks like this:
all_keys = [list(sub_dict.keys()) for sub_dict in my_dict.values()]
which outputs
[['id1', 'id2'], ['id3', 'id4']]
which is halfway to where I want to get.
Adding an asterisk in front of list(sub_dict(keys))
raises a syntax error:
"iterable unpacking cannot be used in comprehension"
Any idea how I get all 'id'-strings in one unnested list with max one additional line of code?
CodePudding user response:
You need to un-ravel the keys of the nested dictionaries, as below:
res = [key for d in my_dict.values() for key in d.keys() if isinstance(key, str) and key.startswith("id")]
print(res)
Output
['id1', 'id2', 'id3', 'id4']
Additionally you need to check that the keys are actually strings (using isinstance
) and then check if they start with "id" (using startswith
).
As an alternative use chain.from_iterable
:
res = [key for key in chain.from_iterable(my_dict.values()) if isinstance(key, str) and key.startswith("id")]
print(res)
Also as suggested by @user2390182 you don't need to use .keys() on the nested dictionaries, just do:
res = [key for sub_dict in my_dict.values() for key in sub_dict if isinstance(key, str) and key.startswith("id")]
CodePudding user response:
You solution is OK and you can correct this with itertools.chain
like below:
>>> from itertools import chain
>>> list(chain.from_iterable(sub_dict for sub_dict in my_dict.values()))
['id1', 'id2', 'id3', 'id4']
By thanks @user2390182 shorted approach:
>>> list(chain.from_iterable(my_dict.values()))
# Or
>>> [*chain(*map(chain, my_dict.values()))]
['id1', 'id2', 'id3', 'id4']
CodePudding user response:
Firstly you need to access to values of the dict then the keys of that value
new_dict=[id for i in my_dict.values() for id in i.keys()]