For a config validation schema I need to have a nested dictionary which repeats itself. For example assume we have the following dictionary:
{
"conf1": "x",
"conf2": "x",
}
Now I want to have a key conf3 which contains the existing dictionary recursively for a maximum amount of iterations (i.e. 3 times)
So the final result needs to look like this:
{
"conf1": "x",
"conf2": "x",
"conf3": {
"conf1": "x",
"conf2": "x",
"conf3": {
"conf1": "x",
"conf2": "x",
}
}
}
I tried to write a recursive function, but with this solution conf3 is repeated indefinitely
def build_nested_configuration_schema(schema: dict, iteration: int = 0) -> dict:
iteration += 1
if iteration == 3:
return schema
schema.update({"conf3": build_nested_configuration_schema(schema, iteration)})
return schema
new_config = build_nested_configuration_schema({"conf1": "x", "conf2": "x"})
>Solution :
Based on my comment, using the copy package will disconnect the pointer reference as your example results in.
import copy
def build_nested_configuration_schema(schema: dict, iteration: int = 0) -> dict:
internal_schema = copy.copy(schema)
iteration += 1
if iteration == 3:
return internal_schema
schema.update({"conf3": build_nested_configuration_schema(internal_schema, iteration)})
return schema
new_config = build_nested_configuration_schema({"conf1": "x", "conf2": "x"})
print(new_config)
Prints
{'conf1': 'x', 'conf2': 'x', 'conf3': {'conf1': 'x', 'conf2': 'x', 'conf3': {'conf1': 'x', 'conf2': 'x'}}}
The main reason this happens is with recursion, python will end up using the value in the method call as a pointer to a value, rather than a separate stored value. That is why your method does return, and does not hit a recursion max limit. The value of conf3 ends up being {conf1: x, conf2: x, conf3: } which is why debugging will show you a never ending stream of conf3 values. The copy method will work, and there may be more pythonic ways to work around the issue, but this will work if the runtime memory is not being tightly managed.