Reputation: 103
I'm working with an API that is returning data in a strange "tree-like" data structure format that I'm trying to convert it to a proper JSON object for re-usability.
It is somewhat like a "tree" structure and I've had luck converting just the "keys" but I'm having trouble associating the values with it. The following answer https://stackoverflow.com/a/9619101/1899406 seems to be a good starting point.
Code:
dct = {}
for key in config.keys():
p = dct
for x in key.split('/'):
p = p.setdefault(x, {})
Starting data:
{ u'key':
u'/parent/child/child2/keyname1',
u'value': u'arbitrary value'},
{ u'key': u'/parent/child/keyname2',
u'value': u'arbitrary value2'},
{ u'key':
u'/parent/child/child2/child3/child4/child5/keyname3',
u'value': u'arbitrary value3'},
{ u'key': u'/parent/keyname4',
u'value': u'arbitrary value4'},
...
Cleaned up slightly:
{{ u'/parent/child/child2/keyname1':
u'arbitrary value'},
{ u'/parent/child/keyname2':
u'arbitrary value2'},
{ u'/parent/child/child2/child3/child4/child5/keyname3':
u'arbitrary value3'},
{ u'/parent/keyname4':
u'arbitrary value4'}}
Desired format(roughly):
{
u'parent': {
u'keyname4': u'arbitrary value4',
u'child': {
u'keyname2': u'arbitrary value2',
u'child2': {
u'keyname1': u'arbitrary value',
u'child3': {
u'child4': {
u'child5': {
u'keyname4': u'arbitrary value4'
}
}
}
}
}
}
}
Upvotes: 3
Views: 478
Reputation: 92440
It seems like you need to split the key values on /
then build an object with each. dict.setdefault()
is super handy here because it lets you grab the a value at a key or set it to a default and grab that if the key is not yet defined.
This uses setdefault()
in reduce
(you could also use a for
loop and just keep track of the current dictionary) to iterate down to the second to last key. Then set the value with the last key:
from functools import reduce
d = {}
for item in tree:
for k, v in item.items():
path = k.split('/')
parent = reduce(lambda curr, x: curr.setdefault(x, {}), path[1:-1], d)
parent[path[-1]] = v
at the end d
should look like:
{'parent': {
'child': {
'child2': {'keyname1': 'arbitrary value',
'child3': {
'child4': {
'child5': {'keyname3': 'arbitrary value3'}
}
}
},
'keyname2': 'arbitrary value2'},
'keyname4': 'arbitrary value4'}
} # i *think* I got the indents right!
Upvotes: 1