I have this nested dictionary (“dictionary of dictionaries”)
source = { "OuterVal0": {"InnerVal": [10, 21, 96],"InnerVal2": [100, 91, 71]}, "OuterVal1": {"InnerVal": [21, 19, 76],"InnerVal2": [1, 1, 1]}, "OuterVal2": {"InnerVal": [1, 1, 96],"InnerVal2": [10, 9, 7]}, "OuterVal3": {"InnerVal": [0, 2, 6],"InnerVal2": [1, 911, 718]}, "OuterVal4": {"InnerVal": [12, 13, 9],"InnerVal2": [1000, 910, 701]}, "OuterVal5": {"InnerVal": [110, 211, 961],"InnerVal2": [10, 911, 918]}, }
And I want to create a new one which would consist of outer keys associated with inner values (see expected output below) I use this recursive function:
def myPrint(d, key=""): output = {} for k, v in d.items(): i = 0 if isinstance(v, dict): return myPrint(v, k) else: for value in d.values(): newkey = (f"{i}_{key}") output[newkey] = value i += 1 return output
But when I try to print that:
print(myPrint(source))
I get this (only the first dictionary is processed:
# {'0_OuterVal0': [10, 21, 96], '1_OuterVal0': [100, 91, 71]}
But I would like to have something like this (all dictionaries processed)
""" Expected output {'0_OuterVal0': [10, 21, 96], '1_OuterVal0': [100, 91, 71]} {'0_OuterVal1':[21, 19, 76], '1_OuterVal1': [1, 1, 1]} . . . {'0_OuterVal5': [110, 211, 961], '1_OuterVal5': [10, 911, 918]} """
What am I doing wrong?
Thank you very much in advance for any help.
Advertisement
Answer
The problem is that when you call return myPrint(v, k)
for the first time you compute the values for the first dictionary and then return instead of continuing to the other values in the for loop.
Changing the function to:
def myPrint(d, key=""): output = {} for k, v in d.items(): i = 0 if isinstance(v, dict): output.update(myPrint(v, k)) else: for value in d.values(): newkey = (f"{i}_{key}") output[newkey] = value i += 1 return output
will return a big dictionary, for you example:
{'0_OuterVal0': [10, 21, 96], '1_OuterVal0': [100, 91, 71], '0_OuterVal1': [21, 19, 76], '1_OuterVal1': [1, 1, 1], '0_OuterVal2': [1, 1, 96], '1_OuterVal2': [10, 9, 7], '0_OuterVal3': [0, 2, 6], '1_OuterVal3': [1, 911, 718], '0_OuterVal4': [12, 13, 9], '1_OuterVal4': [1000, 910, 701], '0_OuterVal5': [110, 211, 961], '1_OuterVal5': [10, 911, 918]}
However, the function can be nicely packed in a non-recursive way as follow:
output = [{f'{ii}_{k}': vv for (k, v) in source.items() for ii, (kk, vv) in enumerate(v.items())}]