The first result is expected as you are adding the list itself, not its values, to copy_l1
. To get the desired result, use either of the following:
copy_l1 += list2
copy_l1.extend(list2)
The second result is harder to understand, but it has to do with the fact that lists are mutable in Python. To understand this, you must first understand what actually happens when you assign one variable to another.
Variable Assignment
When you use var_a = var_b
, both names point to the same variable - that is, the same space in memory; they are just two different ways of accessing it. This can be tested using is
, which checks for identity, not just value:
a = 1
b = a
print(a is b)
# True
So you would expect that changing the value of one name would also affect the other. However, this is not usually the case.
Changing the Value of an Immutable Variable
Most basic data types in Python are immutable. This means that their value can't actually be changed once they are created. Some examples of immutable data types are str
s, int
s, float
s and bool
s.
If the data type of a variable is immutable, then its value can't be changed directly. Instead, when you alter the value of a name pointing it, this is what actually happens:
- A new variable is created
- Its value is set to the new value
- It is given the same name as the name which you are trying to alter - it effectively replaces it
During this process, only one name has had its value changed (or rather, replaced) and any other names pointing to the same variable stay unchanged. You can test that the actual variable the name points to has changed using is
:
a = 5
b = a
print(a is b)
# True
a += 4
print(a is b)
# False
Because of this, the fact that variable assignment works the way it does can almost always be ignored. But this changes when you use mutable variables, such as list
s.
Changing the Value of a Mutable Variable
Because lists are mutable, their value can actually be changed so this three-step process is not necessary. Therefore, all names pointing to the list get changed. You can see this by using is
once again:
a = [1, 2]
b = a
print(a is b)
# True
a += [3, 4]
print(a is b, "again")
# True again
How to Stop this Happening
To stop this from happening, use .copy()
to get a shallow copy of the list:
copy_l1 = list1.copy()
Now both names point to different variables, which happen to have the same value. Operations on one will not affect the other.