For the needs of the project im iterating over some data and adding needed values to premade dictionary.
here is striped down example of code which represents my question:
class Parser:
def __init__(self):
self.records = [['value1','value2','value3'],
['value4','value5','value6'],
['value7','value8','value9']]
def get_parsed(self):
parsed = []
dic = {'key1': '',
'key2': '',
'key3': '',
}
for i in self.records:
dic['key1'] = i[0]
dic['key2'] = i[1]
dic['key3'] = i[2]
parsed.append(dic)
return parsed
What i expect to get is list of dicts like this:
[{'key1':'value1','key2':'value2','key3':'value3'},
{'key1':'value4','key2':'value5','key3':'value6'},
{'key1':'value7','key2':'value8','key3':'value9'}]
But what im getting is:
[{'key1':'value1','key2':'value2','key3':'value3'},
{'key1':'value1','key2':'value2','key3':'value3'},
{'key1':'value1','key2':'value2','key3':'value3'}]
Though if i move dictionary initialization into ‘for’ loop – im getting the desired result but i don’t understand why is that happening?
EDIT:
The question is more “Why does it happens this way”
I did some testing in ipython and that’s what i’ve got:
In [1]: d = {'a':'','b':'','c':''}
In [2]: d
Out[2]: {'a': '', 'b': '', 'c': ''}
In [3]: d['a'] = 'value'
In [4]: d['b'] = 'other_value'
In [5]: d['c'] = 'third_value'
In [6]: d
Out[6]: {'a': 'value', 'b': 'other_value', 'c': 'third_value'}
In [7]: d['a'] = 'inserting new value'
In [8]: d
Out[8]: {'a': 'inserting new value', 'b': 'other_value', 'c': 'third_value'}
So the value of the key could be updated and it changes, why doesn’t it happen in FOR loop?
Because your
dicis created outside the loop, you only create one dict. If you want three different dicts, you need to create three different dicts, so move the initial creation ofdicinside the loop.To answer your updated question, the issue is that although you think you are appending a new dict with each
parsed.append(dic), you are just appending the same dict three times.Appenddoesn’t copy the dict. So whenever you modify that dict, all the dicts inparseshow the change, since they are all the same dict. This version of your second code example may be more illustrative:Notice that changing the dict “works” in that it indeed changes the value, but regardless of that, the list still contains the same dict multiple times, so any changes you make overwrite whatever changes you made earlier. In the end, your list only contains the last version of the dict, because all earlier changes were overwritten in all dicts in the list.