I have a value test-1
and a list of keys as below:
[
["initial", "short_title"],
["later", "datasets", "item_okmiwt"],
["general_title"]
]
I wanted the resulting dictionary like this:
{'initial': {'short_title': 'test-1'}, 'later': {'datasets': {'item_okmiwt': 'test-1'}}, 'general_title': 'test-1'}
I have written the following code for implementing the above result:
def set_copy_to_attr(value, copy_to_attr):
"""Method to copy value to copy_to config."""
def build_nested_dict(element, result={}):
if len(element) == 1:
result[element[-1]] = pid_value
return result
else:
for el in element:
result[el] = {}
element.remove(el)
build_nested_dict(element, result[el])
for _element in copy_to_attr:
_dict = build_nested_dict(_element)
if _dict:
return _dict
I am getting the desired result, Is this approach can be optimized more?
1 Answer 1
Broadly: this kind of dictionary soup is a problem, and is often evidence of inadequate domain modelling and deserialisation. But you haven't shown enough of your actual application to say more.
Two things will slow you down: mutating element
via .remove()
, and recursing. Python is bad at recursing, and for input of sufficient depth this will easily blow the stack.
Add PEP484 type hints - even though, since this is dictionary soup, typing is made more difficult.
Rather than _dict
(making it look like a private), typically to avoid Python keywords, the underscore is a suffix i.e. dict_
.
Suggested
from pprint import pprint
from typing import Any, Iterable
def set_copy_to_attr(
value: Any,
copy_to_attr: Iterable[Iterable[Any]],
) -> dict:
dict_ = {}
for *values, leaf in copy_to_attr:
nested = dict_
for v in values:
nested[v] = nested = {}
nested[leaf] = value
return dict_
def test() -> None:
copy_to_attr = [
["initial", "short_title"],
["later", "datasets", "item_okmiwt"],
["general_title"]
]
copied = set_copy_to_attr('test-1', copy_to_attr)
pprint(copied)
if __name__ == '__main__':
test()
Output
{'general_title': 'test-1',
'initial': {'short_title': 'test-1'},
'later': {'datasets': {'item_okmiwt': 'test-1'}}}
-
\$\begingroup\$ Thanks for the suggestions, for more context, the logic is to add metadata on the basis of some schema config and it is for showing some default values in the UI. \$\endgroup\$ParthS007– ParthS0072022年08月24日 12:48:57 +00:00Commented Aug 24, 2022 at 12:48