Thursday, September 19, 2019

Assignment operator in python vs. copy

Lately I stumbled across the following issue when assigning a variable to another (which was a list) and a change to the original reflected in the second.
(This is in python 3.7. I am not using the python prompt >>> in the examples below.)

x = ['a']
y = x
x.append('b')
print(x)
   ['a', 'b']
print(y)
   ['a', 'b']

An example with int shows this

x = 5
y = x
x = x + 7
print(x)
  12
print(y)
  5

What might seem surprising at first glance totally makes sense:
an assignment '=' is not a copy operation.

The assignment

x = something
rather gives the name tag x to the object something.
y = x
gives the name tag y to the same object which is tagged x.
There is no copy aka. creation of a new object happening here.

The conclusion is:
if the object tagged x is a changeable object any change will be seen in y too.
So if the object is a list, tuple, set, dict etc. a change to the object (like the append operation) is both visible when either accessing x or y.

If the object is an integer or a string then it cannot be changed. Operations like addition create a new object.
x = x + 7 does not change the former object 5 but creates a new object 12.
y is still pointing to the old object and thus shows the old value.

If the intention of the original code was to create a copy of a list then a true copy operation should be used instead.

y = x[:]