I have a nested Python Dict and I am trying to take values from a list and then iterate them into a Dict's values as such:
for row in rows:
Dict[A][AA][AAA] += 1
However, when I print my dict, it appears to be adding all of the increments to all of the Dict entries. By which I mean that instead of this:
{KeyA:{KeyAA:{KeyAAA:5}}}
{KeyB:{KeyBB:{KeyBBB:10}}}
I am getting this:
{KeyA:{KeyAA:{KeyAAA:15}}}
{KeyB:{KeyBB:{KeyBBB:15}}}
I'm a bit stumped.
EDIT: This is how the Dicts were created: I first skim through a long table that contains a type classification. While I'm doing that, I create a new entry into the main Dict. At the same time, I'm collecting all of the unique classifications into a subDict so that I can add this to the main Dict later on:
Dict = {}
subDict = {}
for row in skimRows:
Dict[row[0]] = {"Type":row[1],"Assoc":{}} # Save each ID and origin Type to Dict
if item not in subDict: # Check to see if unique item already exists in subDict
subDict[item] = 0
Here is evidently where I was going wrong. I was then taking the subDict and plunking this into the main Dict, not realising the inserted subDict was retaining its relationship to the original subDict object:
for key in Dict: # After initial iteration and Type collection, add new subDict to each Dict key
Dict[key]["Assoc"] = subDict
SOLUTION: Per the correct answer below, I fixed it by adding .copy()
for key in Dict: # After initial iteration and Type collection, add new subDict to each Dict key
Dict[key]["Assoc"] = subDict.copy()
Your innermost dictionaries are shared, not unique objects:
>>> somedict = {}
>>> somedict['foo'] = {'bar': 0}
>>> somedict['spam'] = somedict['foo']
>>> somedict['foo']['bar'] += 1
>>> somedict['spam']
{'bar': 1}
>>> somedict['foo'] is somedict['spam']
True
The two keys foo
and spam
both are referring to the same object here, one dictionary object holding a key bar
.
You should not reuse your dictionaries like this. Either create a new empty dictiorary:
somedict['spam'] = {'bar': 0}
or create a (shallow) copy:
somedict['spam'] = somedict['foo'].copy()
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments