+= should be the same as = + but its giving me error (list)

hi, beginner here.
I’m learning about lists and i’m having trouble adding something to a list without using the += sign. code below

list1 = []
list1 += "a"
print(list1, type(list1))

list1 = []
list1 = list1 + "a"
print (list1, type(list1))

first example works fine and gives back a list with a single item ‘a’ and class list
but the 2nd example fails with the following error
TypeError: can only concatenate list (not “str”) to list

shouldn’t the += sign work the same as = something + something?
it does so for other variables so why is it failing for lists? also isn’t “a” a string in here? so why was it considered a list when used a += since it was concatinated?

sorry for noob question but i kind of wish to know why rather then just settling to use +=

thanks in advance

Hi Dave,

You’re right, it should. Well, it doesn’t for lists and other mutable sequence types, but that is a perfectly reasonable thing to expect.

For lists, it so happens that + only works with two lists, but += and .extend(...) work with any iterable.

>>> l = []
>>> l += [1,2,3]
>>> l
[1, 2, 3]
>>> l += range(4, 7)
>>> l
[1, 2, 3, 4, 5, 6]
>>> l += 'abc'
>>> l + 'def'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can only concatenate list (not "str") to list
>>> l + ['d', 'e', 'f']
[1, 2, 3, 4, 5, 6, 'a', 'b', 'c', 'd', 'e', 'f']

If you have a list and another iterable, not a list, that you want to add to the list with +, you’ll have to convert it to a list first. Just calling list() should almost always work.

>>> [1,2,3] + list('abc')
[1, 2, 3, 'a', 'b', 'c']
1 Like

To me it does feel a bit unexpected that this works (and in this way, i.e., doing an .extend() and not maybe an .append() or raising an error):

l = [1, 2, 3]
l += 'abc'
l
>>> [1, 2, 3, 'a', 'b', 'c']

What are the reasons for + and += not to have consistent behaviour?

1 Like

I believe many have suggested that this is the “wrong” behavior, and maybe if we could go back in time, += would only take lists. But at this point, the behavior is set, and changing it would probably break more code than it would help.

Also, note that there is another way in which += differs from +: the inplace add operator “+=” does thing s in place if possible (i.e. if the object is mutable), whereas “+” makes a new list:

>>> a0 = []
>>> a = a0
>>> a += [17]
>>> a0 is a
True
>>> a0
[17]

>>> b0 = []
>>> b = b0
>>> b = b + [17]
>>> b0 is b
False
>>> b0
[]
2 Likes

If you want to add something to a list, use the append method:

list1 = []
list1.append(0)

If you want to append many items at once, use the extend method:

list1.extend([1, 2, 4, 8, 16, 32])

# That is the same as:
for obj in [1, 2, 4, 8, 16, 32]:
    list1.append(obj)

# except faster and more convenient.

The extend method will accept any iterable object. That includes
sequences and containers like lists and tuples, iterators (you probably
haven’t learned about them yet!), strings and more.

Strings are iterable as a sequence of individual
characters, so list1.extend("hello") will append each letter
separately:

list1.extend("hello")
# equivalent to:
for char in "hello":
    list1.append(char)

List concatenation using the plus sign requires both arguments to be a
list, since otherwise it is not clear what sort of result you want:

# concatenate a list and a tuple
[0, 1, 2, 3] + (4, 5)

# concatenate a string and a list
"abcdef" + [0, 1, 2, 3]

Should they be a list or a tuple, and a string or a list?

List concatenation with the plus sign may also be inefficient, as it
always has to create a new list. For “adding” only two or three lists,
who cares? But if you add lots of lists, it gets very inefficient and
slow. If you add ten lists together like this:

a = [0] + [1] + [2] + [3] + [4] + [5] + [6] + [7] + [8] + [9]

the Python interpreter has to create nineteen lists and delete eighteen
of them to get the final result.

There has to be a better way, and that way is to use append or the
extend method. Both are in-place and don’t have to create new, temporary
lists and then delete them.

And that brings us to the += augmented assignment operator.

It might look like +, but it is actually a different spelling of
list.extend. So these two lines of code are roughly equivalent:

list1 += obj

list1.extend(obj)

and they work pretty much identically.

Advantages:

  • can accept any iterable, not just another list;

  • appends items in place, so faster and more efficient.

Disadvantages:

  • looks like a variant spelling of + but is actually extend.
2 Likes

thanks guys im soo gonna print all of your replies so i can reference them since you’ve summarized most of the lists common usages/editing.

yea it makes me anxious knowing that what should work alike is actually not.
i’ve come across other (what I think might be) similar not-so-alike behaviour which i can’t understand. In fact i think I might open a new question thread for some explenation on global/local variables inside a function which i can’t understand :confused:

meanwhile thanks a lot all of you for your valuable input!