I have been beating my head against a wall over this problem. I create a list and make 4 copies, only one of which shares the same memory index. If I change the original list, is somehow changes 3 of those copies as well, 2 of which have a different memory index. Only if I make a list using the same command as the original, am I able to create a list that is not impacted by changes to the original. How is this possible? Here is the output from my console:
>>> orig=[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 123, 0]]
>>> id(orig)
151498220
>>> copy1=orig #same index
>>> id(copy1)
151498220
>>> copy2=orig[:] #different index
>>> id(copy2)
151498348
>>> copy3=list(orig) #different index
>>> id(copy3)
151503020
>>> copy4=[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 123, 0]]
>>> id(copy4)
151498636
>>> orig[0][1]=34
>>> copy1
[[0, 34, 0, 0], [0, 0, 0, 0], [0, 0, 123, 0]] #expected, same memory index
>>> copy2
[[0, 34, 0, 0], [0, 0, 0, 0], [0, 0, 123, 0]] #WTF?!?!?
>>> copy3
[[0, 34, 0, 0], [0, 0, 0, 0], [0, 0, 123, 0]] #ARGH!!!
>>> copy4
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 123, 0]] #workaround?
>>> id(orig)
151498220
>>> id(copy1)
151498220
>>> id(copy2)
151498348
>>> id(copy3)
151503020
>>> id(copy4)
151498636
The memory indices did not change and yet the lists were altered. Only copy1 should have changed as it has the same memory index as orig.
That's because you are just creating a shallow copy. You need to create a deep copy instead.
As per copy module doc:
- A shallow copy constructs a new compound object and then (to the extent possible) inserts references into it to the objects found in the original.
- A deep copy constructs a new compound object and then, recursively, inserts copies into it of the objects found in the original.
You can verify it by comparing the id of inner list:
>>> orig=[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 123, 0]]
>>> id(orig)
151498220
>>> copy2=orig[:] #different index
>>> id(copy2)
151498348
>>> id(copy2[0]) == id(orig[0]) # inner list have same id
True
You can create a deepcopy
using copy.deepcopy(x)
:
>>> import copy
>>>
>>> copy3 = copy.deepcopy(orig)
>>>
>>> id(copy3[0]) == id(orig[0]) # inner list have different id
False
>>> orig[0][3] = 34
>>>
>>> orig
[[0, 34, 0, 0], [0, 0, 0, 0], [0, 0, 123, 0]]
>>> copy3
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 123, 0]]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With