What you are experiencing is the concept of references. All objects in Python have a reference and when you assign one to two names a
and b
, this results in both a
and b
pointing to the same object.
>>> a = range(3)
>>> b = a # same object
>>> b.append(3)
>>> a, b # same contents
([0, 1, 2, 3], [0, 1, 2, 3])
With lists, you can make create a new list b
that is a copy of another a
using b = a[:]
.
>>> a = range(3)
>>> b = a[:] # make b a new copy of a
>>> b.append(3)
>>> a, b # a is left unchanged
([0, 1, 2], [0, 1, 2, 3])
For a more general solution for any object, use the copy module. A shallow copy will copy the references stored within the object you're copying, whereas a deep copy will recursively make new copies of all objects.
>>> a = [range(2), range(3)]
>>> b = copy.copy(a) # shallow copy of a, equivalent to a[:]
>>> b[0] = range(4)
>>> a, b # setting an element of b leaves a unchanged
([[0, 1], [0, 1, 2]], [[0, 1, 2, 3], [0, 1, 2]])
>>> b[1].append(3)
>>> a, b # modifying an element of b modifies the element in a
([[0, 1], [0, 1, 2, 3]], [[0, 1, 2, 3], [0, 1, 2, 3]])
>>> a = [range(2), range(3)]
>>> b = copy.deepcopy(a) # deep recursive copy of a
>>> b[1].append(3)
>>> a, b # modifying anything in b leaves a unchanged
([[0, 1], [0, 1, 2]], [[0, 1], [0, 1, 2, 3]])