I have a nested (dictionaries) and (list of dictionaries) - parentheses for clarity - like the following:
{"k":
{"hello": "bye",
"hi": [{"a": "b", "c": "d"}, {"q": "I", "o": "p"}]
}
}
And I want to flatten it into a path like the following:
"k/hello/bye/hi/a/b/c/d/q/I/o/p"
How can this be done? There may be more layers of dictionaries (even within the ones in a list), so I need a very scalable solution.
Thanks, Jack
Recursion hardly ever works first run, guess I was lucky:
def traverse(struct):
if isinstance(struct, dict):
return '/'.join(k+'/'+traverse(v) for k,v in struct.items())
elif isinstance(struct, list):
return '/'.join(traverse(v) for v in struct)
else:
return struct
which gives:
'k/hello/bye/hi/a/b/c/d/q/I/o/p'
why?
Each call to the traverse
function takes a struct
argument which can be either a dictionary, list, or string.
If it is a dictionary, we join together all the values followed by the result of traversing the corresponding keys. We then return this string.
Similarly, if it a list, we join together the outputs of traversing all the elements and return the result.
Finally, if the struct
argument is just a string, we return it to our parent.
In every case, each function is unaware of wear it is in the stack of calls, it just knows what its struct
argument was and returns the correct response for that , argument.
This is what is so cool about recursion, you only need to consider one case, and as long as you write it correctly and pass the right things from parent to child, the result just emerges through cooperation.
NB As @DanielMeseko
notes in the comments, dictionaries aren't ordered so, for instance, the hello
an hi
parts of the final string could "switch places" (along with their children trees).
update
To make the dictionaries sorted by the alphabetical position of the keys, we just need to use the sorted()
function on the result from struct.items()
.
That is to stay: replace struct.items()
in the above code with:
sorted(struct.items())
Which will sort alphabetically be default.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.