'Get all values from nested dictionaries in python
I have some dictionaries of dictionaries, like this:
a['b']['c']['d']['answer'] = answer1
a['b']['c']['e']['answer'] = answer2
a['b']['c']['f']['answer'] = answer3
....
a['b']['c']['d']['conf'] = conf1
a['b']['c']['e']['conf'] = conf2
a['b']['c']['f']['conf'] = conf3
Is there a fast way to get a list of values of all answers for all elements at the third level (d,e,f)?
Specifically I'd like to know if there's any mechanism implementing a wildcard (e.g., a['b']['c']['*']['answer'].values()
update The fastest way I've found till now is:
[x['answer'] for x in a['b']['c'].values()]
Solution 1:[1]
In Python3 we can build a simple generator for this:
def NestedDictValues(d):
for v in d.values():
if isinstance(v, dict):
yield from NestedDictValues(v)
else:
yield v
a={4:1,6:2,7:{8:3,9:4,5:{10:5},2:6,6:{2:7,1:8}}}
list(NestedDictValues(a))
The output is:
[1, 2, 3, 4, 6, 5, 8, 7]
which is all of the values.
Solution 2:[2]
You could use a simple list comprehension:
[a['b']['c'][key]['answer'] for key in a['b']['c'].keys()]
Out[11]: ['answer1', 'answer2', 'answer3']
If you want to get all the answers and conf etc. You could do:
[[a['b']['c'][key][type] for key in a['b']['c'].keys()] for type in a['b']['c']['d'].keys()]
Out[15]: [['conf1', 'conf2', 'conf3'], ['answer1', 'answer2', 'answer3']]
Solution 3:[3]
I would do that using recursive generator function:
def d_values(d, depth):
if depth == 1:
for i in d.values():
yield i
else:
for v in d.values():
if isinstance(v, dict):
for i in d_values(v, depth-1):
yield i
Example:
>>> list(d_values({1: {2: 3, 4: 5}}, 2))
[3, 5]
In your case, this would give a dictionary like {'answer': answer1, 'conf': conf1} as each item, so you can use:
list(d['answer'] for d in d_values(a, 3))
Solution 4:[4]
list(map(lambda key: a['b']['c'][key], a['b']['c'].keys()))
Solution 5:[5]
You can use a NestedDict. First, let me recreate your dictionary
>>> from ndicts.ndicts import NestedDict
>>> nd = NestedDict.from_product("b", "c", "def", ["answer", "conf"])
NestedDict({
'b': {
'c': {
'd': {'answer': None, 'conf': None},
'e': {'answer': None, 'conf': None},
'f': {'answer': None, 'conf': None}
}
}
})
Then use an empty string as a wildcard
>>> nd_extract = nd.extract["b", "c", "", "answer"]
>>> nd_extract
NestedDict({
'b': {
'c': {
'd': {'answer': None},
'e': {'answer': None},
'f': {'answer': None}
}
}
})
Finally get the values
>>> list(nd_extract.values())
[None, None, None]
To install ndicts
pip install ndicts
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | dtc |
| Solution 2 | Ankur Ankan |
| Solution 3 | jonrsharpe |
| Solution 4 | Jerry Wong |
| Solution 5 | edd313 |
