pitosalas
pitosalas

Reputation: 10882

Copy 2d array in Python: Confusion

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

Answers (3)

Blckknght
Blckknght

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

QHarr
QHarr

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

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

Related Questions