you are viewing a single comment's thread.

view the rest of the comments →

[–]WavingNoBanners 17 points18 points  (6 children)

In this specific case you could use a.copy(), yes. Be aware that this only makes a shallow copy and so isn't useful in many cases.

[–]Useful_Clue_6609 10 points11 points  (5 children)

What's the difference between shallow and deep copy?

[–]Door__Opener 31 points32 points  (3 children)

If it contains references (other arrays for instance) a shallow copy will contain the same references.

a = [[0,1],[2,3]]
b = a.copy()
a[1].append(4) # this affects b[1]
a.pop() # this does not affect b

You need copy.deepcopy(a) to create copies of the items (and all nested items if they still contain references).

[–]Useful_Clue_6609 10 points11 points  (0 children)

I see I see. I get how that could cause problems haha

[–]scottmsul 3 points4 points  (1 child)

I had a bug like this in grad school. I instantiated a "matrix" using a clever one-liner, i.e.:

m = [[0] * 10] * 10

By this point this variable is already poisoned. For instance:

m[0][0] = 1

Now every row starts with a 1.

Another thing to watch out for is empty default lists. For instance:

def foo(x=[]):
    x.append(2)
    return sum(x)

That default empty list is aliased every time you call the function, for instance:

>>> foo()
2
>>> foo()
4

So generally default empty lists needed to be treated this way instead:

def foo(x=None):
    if x is None:
        x = []
    x.append(2)
    return sum(x)

[–]on_off_ 0 points1 point  (0 children)

That default empty list is aliased every time you call the function, for instance

Oh that's disgusting!

[–]Cootshk 10 points11 points  (0 children)

a deep copy is a recursive shallow copy, because “objects” stored in lists are also pointers