After Python 3.7, dictionaries are order-preserving. This allows us to get values as follows:
a = list(dict.values())[idx]
What I want to do is to set a value, which is nested as follows. There is an outer dictionary, its first value is an instance of a class. This class has another dictionary as attribute, and I would like to change the first value in this dictionary.
a = list(list(outer_dict.values())[0].dict_as_attribute.values())[0]
a = 1
How do I put the new a
back to its place? The above expression gives me a copy, and when I change a
, the one in the dictionary stays the same. Ofcourse, the following also doesn't work:
list(list(outer_dict.values())[0].attribute.values())[0] = a
Solutions using known keys or using different data structures don't help: I am not allowed to change the data structure and I also do not know the keys.
Thanks for the answers.
CodePudding user response:
You can get the keys in the same way as you get the values:
outer_key = list(outer_dict.keys())[0]
inner_key = list(list(outer_dict.values())[0].attribute.keys())[0]
outer_dict[outer_key].attribute[inner_key] = a
CodePudding user response:
outer_key = next(iter(outer_dict.keys()))
inner_key = next(iter(outer_dict[outer_key].dict_as_attribute.keys()))
outer_dict[outer_key].dict_as_attribute[inner_key] = a
This avoids creating lists containing all the keys, so is more efficient.
CodePudding user response:
You need to keep a reference to the dict key, you want to change:
# dummy class
class A:
def __init__(self):
self.dict_as_attribute = {
'foo': 'FOO',
'bar': 'BAR',
'baz': 'BAZ'
}
outer_dict = {
chr(k): A() for k in range(80, 85)
}
outerIndexToChange = 3
innerIndexToChange = 2
newValue = 'FOOBAR'
# change dict value
outerReference = outer_dict[list(outer_dict.keys())[outerIndexToChange]].dict_as_attribute
outerReference[list(outerReference.keys())[innerIndexToChange]] = newValue
# verify
for v in outer_dict.values():
print(v.dict_as_attribute)
Out:
{'foo': 'FOO', 'bar': 'BAR', 'baz': 'BAZ'}
{'foo': 'FOO', 'bar': 'BAR', 'baz': 'BAZ'}
{'foo': 'FOO', 'bar': 'BAR', 'baz': 'BAZ'}
{'foo': 'FOO', 'bar': 'BAR', 'baz': 'FOOBAR'}
{'foo': 'FOO', 'bar': 'BAR', 'baz': 'BAZ'}