So, I have read quite a few posts on flattening dictionaries recursively in Python. None (save one) have come close to what I'm looking for. First, a quick example of what I am trying to accomplish:
Example dictionary with mixed entries: (keys and values will always be of mixed types)
{'a': [{'b': {'c': 'd', 'e': 'f', 'g': 'h',
'i': {'j': {'k': ['l'], 'm': 'n'}},
'o': {'p': {'q': ['r', 's' ], 't': 'u'}}
}
}]
}
Desired output:
{'a/b/c/d',
'a/b/e/f',
'a/b/g/h',
'a/b/i/j/k/l',
'a/b/i/j/m/n',
'a/b/o/p/q/r',
'a/b/o/p/q/s',
'a/b/o/p/t/u'}
The function should (theoretically) work on lists as well.
To explain a bit about what I am doing, I am attempting to search through a Mac plist and other attempts to search by key or value have been shaky at best. To compensate, I want to try a different approach. Convert the dictionary to a list of 'paths' and then just search the paths.
I tried myself (and partially succeeded) and then I found a better solution in the form of this:
def flatten(structure, key="", path="", flattened=None):
if flattened is None:
flattened = {}
if type(structure) not in(dict, list):
flattened[((path + "/") if path else "") + key] = structure
elif isinstance(structure, list):
for i, item in enumerate(structure):
flatten(item, "", "/".join(filter(None,[path,key])), flattened)
else:
for new_key, value in structure.items():
flatten(value, new_key, "/".join(filter(None,[path,key])), flattened)
return flattened
This works well but there are a few undesired effects. First, the output is as follows:
{'a/b/c' : 'd',
'a/b/e' : 'f',
'a/b/g' : 'h',
'a/b/i/j/k/': 'l',
'a/b/i/j/m' : 'n',
'a/b/o/p/q/': 's',
'a/b/o/p/t' : 'u'}
This is returning a dictionary of key/value pairs. I'd rather have a list of string paths. Secondly, and more importantly, you'll notice, the script has stripped values where the value was a list. Only appending the last item of the list.
'a/b/o/p/q/': 's' # there should be another entry with 'r' as the value.
I have spent a fair amount of time fiddling with the output and trying to completely wrap my head around the problem to no avail. It may just be my lac of understanding Python, but the output I want should be possible.
I try not to ask questions unless I have run out of options and here I am. Please do not mark as a duplicate, as other questions aren't quite looking to accomplish what I am looking for.
Thank you for your time and assistance/guidance.