Python Forum
Theory behind referencing a dictionary rather than copying it to a list - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: Theory behind referencing a dictionary rather than copying it to a list (/thread-25242.html)



Theory behind referencing a dictionary rather than copying it to a list - sShadowSerpent - Mar-24-2020

Hi there, I ran into a problem working with appending a dictionary to a list today. I eventually managed to figure out that appending a dictionary to a list without copying it is just appending a reference to that dictionary. Anyway I fixed it but I don't understand why:

In this code (the broken code), when I eventually print out my list I just get the same dictionary rather than different ones, which I understand happens because I referenced the dictionary rather than appending a copy to it each time.

labUpgradeDict = {}
for row in labTableRows:
		cells = row.find_all("td")
		for cell in cells:
			labUpgradeDict[labTableHeaderSimplified[cells.index(cell)]] = cell.getText().replace('\n', '').strip()
			labUpgradeList.append(labUpgradeDict)
Anyway I eventually changed my code to this, (changed the indent of the append for different reasons) and set the dictionary to being empty in the for loop.

for row in labTableRows:
		labUpgradeDict = {}
		cells = row.find_all("td")
		for cell in cells:
			labUpgradeDict[labTableHeaderSimplified[cells.index(cell)]] = cell.getText().replace('\n', '').strip()
		labUpgradeList.append(labUpgradeDict)
Now this worked but I don't understand why because I'm still referencing the dictionary rather than appending a copy. Each entry in my final list had a different dictionary yet I'm just appending a reference to it so I thought that the final list would just contain a recurring dictionary. Yet it doesn't

This code over here is what I would think is correct:

for row in labTableRows:
		labUpgradeDict = {}
		cells = row.find_all("td")
		for cell in cells:
			labUpgradeDict[labTableHeaderSimplified[cells.index(cell)]] = cell.getText().replace('\n', '').strip()
		labUpgradeList.append(labUpgradeDict.copy())
And it works in the same way as the code without the .copy().

Basically what I'm asking is in the first code. The whole idea of referencing breaks it BUT in the second code it works where I changed nothing but indentation and moving where I reset the dictionary, something which I'd think have no effect on referencing the dictionary, yet all of a sudden I get different copies of the same referenced dictionary unlike before where I just got a recurring copy.


RE: Theory behind referencing a dictionary rather than copying it to a list - stullis - Mar-24-2020

Moving the dict instantiation into the loop fixed it. Previously, you were referencing the same dict multiple times in a list. That means any update to the dict will update every reference in the list because they all get their information from the same memory location.

Inside the loop, the dict instantiation creates a new dict stored at a different memory location each time. Even though you're appending the same variable to the list, that variable has a different reference every time the loop runs.

out= []
for x in range(10):
    example = {}
    out.append(example)
    print(id(example))
Output:
52431536 55345824 55345728 55345680 55346208 55347456 55346256 55346304 55346352 55346400
Compared to the original:

out = []
example= {}
for x in range(10):
    out.append(example)
    print(id(example))
Output:
55345968 55345968 55345968 55345968 55345968 55345968 55345968 55345968 55345968 55345968



RE: Theory behind referencing a dictionary rather than copying it to a list - sShadowSerpent - Mar-24-2020

Thanks a lot!