Here is a iterative solution:
data = [
{"key": "global.person.name", "value": "john doe"},
{"key": "global.person.age", "value": "20"},
{"key": "global.name", "value": "my program"},
{"key": "program", "value": "test01"},
{"key": "active", "value": "true"}
]
result = {}
for item in data:
current = result
*key_parts, last_key_part = item["key"].split('.')
for key_part in key_parts:
current = current.setdefault(key_part, {})
current[last_key_part] = item["value"]
print(result)
I'm taking advantage of iterable unpacking to in the line *key_parts, last_key_part = item["key"].split('.')
to more concisely write code that puts all but the last part of the key into key_parts
, and the last part into last_key_part
. The dict.setdefault
method is useful when you want to access an item of a dict
or create a new entry in the dict if the key is not present.
Alternatively, taking inspiration from an answer to a similar question, it can be made recursive:
def add_item(obj, key, value):
first, match, rest = key.partition('.')
if rest:
# recurse
add_item(obj.setdefault(first, {}), rest, value)
else:
# this is the last part of the key, so use it to enter the value rather than recursing
obj[first] = value
result = {}
for item in data:
add_item(result, item["key"], item["value"])
print(result)
This version is equivalent to the iterative version, just written differently. It is different from the answer I used as inspiration since it doesn't need to deal with list indices but it does need to be able to create new entries in dictionaries rather than just modify existing values.