Reputation: 10882
My understanding is that:
def copy_2d(p):
return list(p)
Would make a full copy of p and return it as a result. list( p) seems to do this when I try it in the repl. However it seems like calling the above method like this:
b = [[1,2,3],[3,4,5]]
a = copy_2d(b)
a[0][0] = 0
if (b[0][0] == 0): print "Huh??"
It prints "Huh??", that is, it appears that b is just a reference to a. I double checked but I might be blind. Can someone clarify please?
Upvotes: 0
Views: 4013
Reputation: 104722
Your current code for copy_2d
returns a shallow copy of the list you pass as its argument. That is, you're creating a new outer list, but the inner values (which may be lists themselves) are not copied. The new list references the same inner lists, so when you mutate one of them, you'll see the same change in the shallow copy as you do in the original list.
You can fix the issue by copying the inner lists as well as creating a new outer list. Try:
def copy_2d(p):
return map(list, p) # warning: this only works as intended in Python 2
In Python 2, this works because map
returns a list. In Python 3, the map
function returns an iterator, so a list comprehension like [list(inner) for inner in p]
would be better.
Of course, if you don't need to write your own code to solve this problem, you should just use copy.deepcopy
from the standard library.
Upvotes: 4
Reputation: 84465
Shallow copy made. Same logic as here?what-does-the-list-function-do-in-python
"list() converts the iterable passed to it to a list. If the iterable is already a list then a shallow copy is returned, i.e only the outermost container is new rest of the objects are still the same."
Upvotes: 2
Reputation: 527
import copy
def copy_2d(p):
return copy.deepcopy(p)
or
def copy_2d(p):
return [list(p2) for p2 in p]
What you did copied the array with all the values inside. But inside you had objects with were arrays. Your function did not copied inside lists but their references.
The second solution still copies references, but one layer below.
Upvotes: 2