Reputation: 33
def foo(image):
res = image[:]
for i in range(3):
for j in range(3):
res[i][j] = 1
return image
foo([[0,0,0],[0,0,0],[0,0,0]])
For the above function, I copied the image to res and only modified res inside the function. So I assumed that calling the function should return the same as my input. However, the output is a 3 by 3 arrays with all ones. Could anyone explain this to me, please? Thanks.
I guess it is something related to local and global variables, but I am not sure. If I want to clone the image to res and only change the values for res, how am I supposed to manage it?
Upvotes: 0
Views: 116
Reputation: 26
You're seeing this behaviour because res
is a shallow copy of image
.
To see the behaviour you expected you will need to create a deep copy instead, luckily the standard library includes a way to do this for simple cases.
import copy
def foo(image):
res = copy.deepcopy(image)
for i in range(3):
for j in range(3):
res[i][j] = 1
return image
foo([[0,0,0],[0,0,0],[0,0,0]])
If you don't want to bring in another dependency, then you can get the same result with a list comprehension.
def foo(image):
res = [x[:] for x in image]
for i in range(3):
for j in range(3):
res[i][j] = 1
return image
foo([[0,0,0],[0,0,0],[0,0,0]])
Lists in python are by reference, not value, the same list can be accessed by different names.
We can see this by running the following:
import copy
original = [[1]]
shallow_copy = original[:]
deep_copy = copy.deepcopy(original)
shallow_copy[0][0] = 2
print(original)
print(deep_copy)
When you copy a list with image[:]
, python does the following:
image
, add the same item to the new list.It does not copy the internal lists, it just points to the original one.
As a result original
and shallow_copy
are different lists, but original[0]
and shallow_copy[0]
are the same list.
Upvotes: 1
Reputation: 2094
In your code res = image[:]
creates a shallow copy of the res
list. The difference between shallow and deep copying is only relevant for compound objects (objects that contain other objects, like lists, dicts, sets or class instances):
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.
So, in your code both res
and image
contain references to the same list objects.
[Source]
Upvotes: 1