I'm trying to create a multiple hierarchy of nested dictionary. The hierarchy levels are separated with a dot(.) in variable B
however the final key (A
) and value (D
) are fixed.
Variables
A = "key"
B = "one.two.three.four"
D = "value"
Desired Output
{ one : { two : {three : {four : {key: value}}}}}
Here, the length of hierarchy (variable B
) might increase or decrease based on input. I'm unable to create such dynamic code.
My pseudocode Code
A = "key"
B = "one.two.three.four"
D = "value"
inner_dictionary = {}
whole_dictionary = {}
lst = B.split('.')
length = len(lst)
for i in range(length):
new = lst[-1]
tmp = {A:D}
inner_dictionary.update(tmp)
val = { new : inner_dictionary}
whole_dictionary.update(val)
lst.pop()
print(whole_dictionary)
My Output
{'four': {'key': 'value'}, 'three': {'key': 'value'}, 'two': {'key': 'value'}, 'one': {'key': 'value'}}
I need help on this. Thanks in advance!
CodePudding user response:
Use this:
A = "key"
B = "one.two.three.four"
D = "value"
x = {A: D}
for k in B.split('.')[::-1]:
x = {k: x}
print(x)
Output:
{'one': {'two': {'three': {'four': {'key': 'value'}}}}}
Or, in Python 3.8 , using the walrus operator:
A = "key"
B = "one.two.three.four"
D = "value"
x = {A: D}
[(x := {k: x}) for k in B.split('.')[::-1]]
print(x)
Output:
{'one': {'two': {'three': {'four': {'key': 'value'}}}}}
Note: the second solution takes a lot more time (you can run the following code to check that):
from timeit import timeit
print(timeit("""A = "key"
B = "one.two.three.four"
D = "value"
x = {A: D}
for k in B.split('.')[::-1]:
x = {k: x}"""))
print(timeit("""A = "key"
B = "one.two.three.four"
D = "value"
x = {A: D}
[(x := {k: x}) for k in B.split('.')[::-1]]"""))
The first one takes about 0.5s, the second one about 1s.
CodePudding user response:
One approach using a single for-loop:
A = "key"
B = "one.two.three.four"
D = "value"
start = { A: D }
for k in reversed(B.split(".")):
start = { k : start }
print(start)
Output
{'one': {'two': {'three': {'four': {'key': 'value'}}}}}
This type of problem where a list of values aggregates to a single one can be solved using reduce
(a la functional programming):
from functools import reduce
A = "key"
B = "one.two.three.four"
D = "value"
res = reduce(lambda x, y: {y: x}, reversed(B.split(".")), {A: D})