55
votes

I want to copy a 2D list, so that if I modify one list, the other is not modified.

For a one-dimensional list, I just do this:

a = [1, 2]
b = a[:]

And now if I modify b, a is not modified.

But this doesn't work for a two-dimensional list:

a = [[1, 2],[3, 4]]
b = a[:]

If I modify b, a gets modified as well.

How do I fix this?

2
A whole lot of the time when people user nested lists and need to copy them in this way, they really want to be using numpy. - Mike Graham
imho, that's just a bug in the language. behavior that's different for two cases where it should be identical - typical for interpreted languages. if you have large code, very difficult to debug - Serhii
@SerhiiPoklonskyi No, it's not a bug. When you do b = a[:], you create a new list b, so for example a.append([5, 6]) will not modify b, as it just changes a. However, the line a[1][0] = 5 will change b because it changes a list that b refers to. - Artemis
@ArtemisFowl doesn't work for me (a[1][0] does not modify b as well). Even if it would, I don't understand how that is relevant. The problem is: when you do a = b.copy(), a becomes a separate place in memory: neither reference nor pointer to b, i.e. it's an independent variable. However, if you do a = b.copy() and b is an array, that does not work. how may there be any logical explanation for that? if b is an array, a = b.copy() MUST create an independent variable. otherwise it's a bug. p.s. no intention to be rude, pls explain to me if I am wrong - Serhii
@SerhiiPoklonskyi I think the reason that you find this confusing is that you miss-understand Python. Python does not actually have '2-dimensional arrays' as such, it just has lists, which can contain other lists. I will try to demonstrate by means of an example: you define a with a = [[1, 2], [3, 4]]. Then you create a copy of a: b = a.copy. This is a different list, but it contains the same 'sub-lists' this means that changing b, for example b.append([5, 6]) will not change a, however changing a list in b, for example b[0].append(3) will also change the first list of a. - Artemis

2 Answers

76
votes

For a more general solution that works regardless of the number of dimensions, use copy.deepcopy():

import copy
b = copy.deepcopy(a)