Reputation: 317
I encountered a (in my opinion) extremely strange behavior, when looping through a list of lists. It is very difficult to explain, but here is an example code:
k = [[0],[1],[2]]
for lis in k:
lis_copy = lis
lis_copy.append(0)
print lis
When executing this, I get:
[0, 0]
[1, 0]
[2, 0]
This is very strange for me, as the list which is appended is a copy of lis, but lis is appended as well. I would assume this list to be untouched. For example doing the same with a list of integers the following happens:
k = [0,1,2]
for num in k:
num_copy = num
num_copy = 0
print num
Output:
0
1
2
Just as expected num is not touched by the manipulation of num_copy.
If somebody could explain why this is happening and how to avoid this, like how to disconnect the lis_copy from is, that would be great.
Wow, I am amazed I did not encounter mayor problems before, without knowing this. I think I should review quiet some of my code. Anyway I thought this is somehow connected to the loop, this seems not to be the case, therefore I think the best explanation can be found here:
Upvotes: 2
Views: 118
Reputation: 1803
You could use copy.copy()
or copy.deepcopy()
to avoid this behavior:
import copy
k = [[0],[1],[2]]
for lis in k:
lis_copy = copy.copy(lis)
lis_copy.append(0)
print lis
Output:
[0]
[1]
[2]
Source: https://docs.python.org/2/library/copy.html
Upvotes: 1
Reputation: 916
Case a:
k = [[0],[1],[2]]
for lis in k:
lis_copy = lis
lis_copy.append(0)
print lis
We have a pointer to a list, and inside the loop we have another pointer made that points to the inner list objects. Then a zero is appended to each object.
Case b:
k = [0,1,2]
for num in k:
num_copy = num
num_copy = 0
print num
We have a pointer to a list, and inside the loop we have another pointer made that points to the inner integers. The difference is that in this case the pointer is changed to then point to a zero object rather than the list elements.
Upvotes: 1
Reputation: 141
This is because Python lists (and dicts) are not copied to a new list, but the new list becomes a reference to that list. if you truly want to copy the list, use deepcopy
Upvotes: 2