Single dictionary of fewer keys from a multi level dictionary

182 views Asked by At

I am looking for a way to get values from variable depth in a multi level dictionary. I have a list of keys that are to be looked upon in the multi level dictionary. This key and value is to be put into a new dictionary.

needed_keys = ["a1", "b1", "c1", "d1", "e1"]
original_dict = {"x" : {"xa1" : 5, "xaa" : True, "xaaa" : {"xaaab1" : True, "xaaabb" : False}}, "y" : {"yz" : 6.0, "yc1" : 7.0, "yf" : {"yfd1" : "a string"}}}

final_result = {"a1" : 5, "b1" :True, "c1" : 7.0, "d1" : "a string", "e1" : None}

So basically this:

  1. Get a key name to be looked upon
  2. Traverse the dictionary and check whether dict_key.endswith(key_name)
  3. Assign the value from the original_dict, if found; set to None otherwise
  4. Repeat from 1 until the end of the list

Is this possible with less traversing through the original_dict? This is optional as speed is not an issue here. I am totally lost in here with less messy code.

1

There are 1 answers

2
jonrsharpe On BEST ANSWER

Is this possible with less traversing through the original_dict?

You could flatten out the dictionary recursively:

def flatten(aDict, output=None):
    if output is None:
        output = {}
    for key in aDict:
        if isinstance(aDict[key], dict):
            flatten(aDict[key], output)
        output[key] = aDict[key]
    return output

Now it is easy to get keys at any level.

final_output = {}
flat_dict = flatten(original_dict)
for key in needed_keys:
    for k in flat_dict:
        if k.endswith(key):
            final_output[key] = flat_dict[k]
            break
    if not key in final_output:
        final_output[key] = None