If I have a dictionary of dictionaries, of arbitrary depth, how could I list all of the keys that are in the dictionary, at a given depth? or get a list of the keys in the dictionary and their depths?
For example, a simple dictionary would be:
dict_o_dicts = {'a': {1:'bob', 2: 'fred', 3: 'henry'},
'b': {2:'fred',3: 'henry', 4: 'pascale'}
}
and I'd like a command that does something along the lines of:
print keys_at_depth(dict_o_dicts, 0)
would return: ['a', 'b']
and print keys_at_depth(dict_o_dicts, 1)
would return [1,2,3,4]
I can recursively walk the dictionary to find the maximum depth of the dictionary, but as soon as I try and report both the depth and the key values I end up breaking the recursion.
Thanks
This routine will recursively return a dict
ionary of set
s of the keys at each depth:
def keys_by_depth(dict_, depth=0, output=None):
if output is None:
output = {}
if not depth in output:
output[depth] = set()
for key in dict_:
output[depth].add(key)
if isinstance(dict_[key], dict):
keys_by_depth(dict_[key], depth+1, output)
return output
Gives the output:
{0: {'b', 'a'}, 1: {1, 2, 3, 4}}
Note that this will work with a mix of dictionary and non-dict
values at each level. For only keys at a given depth, you can call and access in one go:
>>> print(keys_by_depth(dict_o_dicts)[1])
{1, 2, 3, 4}
The assumption is that, all levels have valid dicts
dict_o_dicts = {'a': {1:'bob', 2: 'fred', 3: 'henry'},
'b': {2:'fred',3: 'henry', 4: 'pascale'} }
from itertools import chain
def keys_at_depth(d, l):
if l == 0: return d.keys()
elif l > 0: return set(chain.from_iterable([keys_at_depth(d[k], l - 1) for k in d]))
print keys_at_depth(dict_o_dicts, 1)
Output
set([1, 2, 3, 4])
Recursive approach:
def key_at_depth(dct, dpt):
if dpt > 0:
return [
key
for subdct in dct.itervalues()
for key in key_at_depth(subdct, dpt - 1)
]
else:
return dct.keys()
dict_o_dicts = {
'a': {1: 'bob', 2: 'fred', 3: 'henry'},
'b': {2: 'fred', 3: 'henry', 4: 'pascale'},
}
key_at_depth(dict_o_dicts, 0)
Out[69]: ['a', 'b']
key_at_depth(dict_o_dicts, 1)
Out[70]: [1, 2, 3, 2, 3, 4]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With