Why does augmented assignment behave differently when adding a string to a list

285 Views Asked by At

I am in a very interesting situation and I am so surprised. actually I thought both i += 1 and i = i + 1 are same. but it'is not same in here;

a = [1,2]
a += "ali"

and output is [1,2,"a","l","i"]

but if I write like that;

a = [1,2]
a = a + "ali"

it doesn't work.

I am really confused about this. are they different?

3

There are 3 best solutions below

0
On

In python, since you can't declare static types, this behavior doesn't show up, but if you look at C++, if you declare int a = 4 as an integer and then do a += 5.4, a will become 9, whereas a = a + 5.4 will break.

The reason for this is that a += b and a = a + b aren't the same. In python terms, a += b is just a.__iadd__(b) and a = a + b is a = a.__add__(b), or if that doesn't exist, a = b.__radd__(a). You can't add lists and strings together using + so the second code doesn't work, but += works because it automatically casts certain types to each other, namely converting iterables to each other. You cannot do a = []; a += "" but you can do it vice-versa because you can convert the string to a list unambiguously using list("...").

0
On
>>> a = [1,2]
>>> a = a + "ali"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can only concatenate list (not "str") to list

For list data type use the .append method:

>>> a = [1,2]
>>> a.append("ali")
>>> a
[1, 2, 'ali']

The String in Python is defined as a series of characters in a row. So, these "characters" are added to the "list" type as the characters, not as "String". When you want use the += adding operator for the list type, you must specify the type of the added variable or value using square brackets:

>>> a = [1,2]
>>> a += ["ali"]
>>> a
[1, 2, 'ali']

>>> a += ["foo",3,"bar"]
>>> a
[1, 2, 'ali', 'foo', 3, 'bar']
0
On

Short answer

The + operator concatenates lists while the += operator extends a list with an iterable.

Long answer

The + operator concatenate lists to return a new list...

l1 = l2 = []
l1 = l1 + [1]

l1 # [1]
l2 # []

... while the += operator extends a list, by mutating it.

l1 = l2 = []
l1 += [1]

l1 # [1]
l2 # [1]

What allows different behaviours is that + calls the __add__ method while += calls the __iadd__ method.

In your example, you provided a string to the __iadd__ method, which is equivalent to doing l.extend('ali'). In particular, you can extend a list with any iterable, but concatenation arguments must both be lists.

Although, there is a slight difference between list.__iadd__ and list.extend. The former returns the mutated list, while the later does not.