A strange list concatenation result

Steven D'Aprano steve+python at pearwood.info
Thu Aug 11 19:45:56 EDT 2016


Note that your subject line is wrong. You are not doing list concatenation.

Unfortunately, for technical and optimization reasons, the += assignment
operator for lists is in-place, which means that it is NOT the same as
ordinary list concatenation + operator. It is equivalent to calling the
list.extend method.

If you want to do concatenation, creating NEW lists on every operation, you
have to write it the expanded way:

list1 = list1 + list2
# creates a new list from the concatenation of list1 and list2


Your code starts like this:

list1 = list2 = [1, 2, 3]

That is NOT two different lists with equal contents, but ONE list with two
names. You can see this with this:


py> list1 = list2 = [1, 2, 3]
py> list1.append(4)
py> list2
[1, 2, 3, 4]
py> list1 is list2  # Are they the same object?
True


So what happens when you do an in-place extend of a list to itself? You
should be able to guess from the example of append:

py> list1.extend(list2)
py> list2
[1, 2, 3, 4, 1, 2, 3, 4]

list1 will be the same, because list1 and list2 are the same list. Using +=
will give the same results.

So you have two gotchas here:

a = b = [1, 2, 3]

gives you the same list with two names. You could make a copy:

a = [1, 2, 3]
b = a[:]  # using slicing

or:

import copy
a = [1, 2, 3]
b = copy.copy(a)

The second gotcha is that += is not always equivalent to + and in particular
for lists it is equivalent to calling the extend() method.



-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.




More information about the Python-list mailing list