Reputation: 1334
I am working with Python 3.8.5
I have created some objects like this:
class TestClass:
def __init__(self, key, value):
self.key=key
self.value=value
test1 = TestClass(1, 'a')
test2 = TestClass(2, 'b')
test3 = TestClass(3, 'c')
test_list = [test1, test2, test3]
I want to create a dictionary to keep track the modifications in this objects:
object_mapper = {
'ClassNotRelevant': None,
'TestClass': None,
'ClassNotRelevant2': None,
}
test_dict = {test.key: object_mapper for test in test_list}
#output
{1: {'ClassNotRelevant': None, 'TestClass': None, 'ClassNotRelevant2': None},
2: {'ClassNotRelevant': None, 'TestClass': None, 'ClassNotRelevant2': None},
3: {'ClassNotRelevant': None, 'TestClass': None, 'ClassNotRelevant2': None}}
Now, I want to set the value property for each class in the dictionary, like this:
#expected dictionary
#output
{1: {'ClassNotRelevant': None, 'TestClass': 'a', 'ClassNotRelevant2': None},
2: {'ClassNotRelevant': None, 'TestClass':'b', 'ClassNotRelevant2': None},
3: {'ClassNotRelevant': None, 'TestClass':'c', 'ClassNotRelevant2': None}}
I am trying to do the following:
for test in test_list:
test_dict[test.key]['TestClass']= test.value
but the output is:
{1: {'ClassNotRelevant': None, 'TestClass': 'c', 'ClassNotRelevant2': None},
2: {'ClassNotRelevant': None, 'TestClass': 'c', 'ClassNotRelevant2': None},
3: {'ClassNotRelevant': None, 'TestClass': 'c', 'ClassNotRelevant2': None}}
I have tried the different solutions found in: Updating nested dictionaries when data has existing key
But anything worked, what I am doing wrong?
Upvotes: 1
Views: 63
Reputation:
Here is the code which will solve the question. It will create a copy of the object_mapper
for each iteration.
test_dict = {test.key: object_mapper.copy() for test in test_list}
for test in test_list:
test_dict[test.key]['TestClass']=test.value
print(test_dict)
Upvotes: 0
Reputation: 1014
The problem lies here
When you do this
test_dict = {test.key: object_mapper for test in test_list}
Output is
{1: {'ClassNotRelevant': None, 'TestClass': None, 'ClassNotRelevant2': None},
2: {'ClassNotRelevant': None, 'TestClass': None, 'ClassNotRelevant2': None},
3: {'ClassNotRelevant': None, 'TestClass': None, 'ClassNotRelevant2': None}}
This {'ClassNotRelevant': None, 'TestClass': None, 'ClassNotRelevant2': None}
is the same object (object_mapper
) corresponding to key `1 2 3'
So when you update using this :
for test in test_list:
test_dict[test.key]['TestClass']= test.value
This updates the object_mapper
object so,
After 1st iteration:
{1: {'ClassNotRelevant': None, 'TestClass': 'a', 'ClassNotRelevant2': None},
2: {'ClassNotRelevant': None, 'TestClass': 'a', 'ClassNotRelevant2': None},
3: {'ClassNotRelevant': None, 'TestClass': 'a', 'ClassNotRelevant2': None}}
2nd Iteration
{1: {'ClassNotRelevant': None, 'TestClass': 'b', 'ClassNotRelevant2': None},
2: {'ClassNotRelevant': None, 'TestClass': 'b', 'ClassNotRelevant2': None},
3: {'ClassNotRelevant': None, 'TestClass': 'b', 'ClassNotRelevant2': None}}
3rd Iteration
{1: {'ClassNotRelevant': None, 'TestClass': 'c', 'ClassNotRelevant2': None},
2: {'ClassNotRelevant': None, 'TestClass': 'c', 'ClassNotRelevant2': None},
3: {'ClassNotRelevant': None, 'TestClass': 'c', 'ClassNotRelevant2': None}}
So Instead of
test_dict = {test.key: object_mapper for test in test_list}
use
test_dict = {test.key: object_mapper.copy() for test in test_list}
which will create shallow_copy
of object_mapper
object for each entry, instead of putting object_mapper
object itself there.
Upvotes: 2