Reputation: 287
Slicing in python is supposed to make a shallow copy. However, when I run the following:
cur = [[0] * (2) for _ in xrange(2)]
cur2 = [row[:] for row in cur]
cur2[0][0] = "foo"
print(cur)
print(cur2)
I get:
[[0, 0], [0, 0]] # cur
[['foo', 0], [0, 0]] # cur2
which makes it seem like it's a deep copy.
I have two questions: 1) What's happening here? Is this a deep or shallow copy? 2) What about this syntax makes it so much faster than copy.deepcopy? For example, is it something with the way python manages memory?
Upvotes: 0
Views: 843
Reputation: 95948
You are making shallow copies of the inner lists (i.e. the rows), which is effectively the same as a deep copy of the outer list if the inner lists are just lists of int
objects.
You've essentially implemented a deep copy function for the special case of a list of lists of integers.
Using copy.deepcopy
will be slower because that function will have to investigate and cache all id's of the objects, including the int
objects. Your snippet isn't doing that, but in this particular case, it doesn't matter (note, small int
objects are cached at the interpreter level, they are essentially singletons, and anyway, int
objects are immutable so they don't really have to be copied at all).
Here's a link to the copy
module source code if you eant to see exactly what is involved in a generic deep-copy.
Upvotes: 1
Reputation: 20414
I think you have a misunderstanding of what a shallow and a deep copy is.
A shallow copy copies the structure of a collection (essentially the memory locations), whereas a deep copy duplicates everything (as in the actual data) in memory.
What you are doing here is forming a new list of copies of each of the sub-lists from the original 2d list - thus resulting in an entirely new list with no ties to the original list - therefore you have done a deep copy.
If, instead, you were to do: cur[:]
, you would just be copying the outer list that contains the same references to the inner list - therefore a shallow copy.
In your case, as all the memory locations are different, changing one element does not effect the original, but if you were to just do cur[:]
, then the inner rows would reference the same locations in memory, so changing elements from either list would effect the other list.
Upvotes: 1