6

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?

Georgy
  • 12,464
  • 7
  • 65
  • 73
Njx
  • 121
  • 6
  • 4
    Well... `i += 1` and `i = i + 1` is not the same. The former modifies existing object `i` whereas the latter creates a new object. Try also `a=[]; b=a; a+=[1]` - it modifies both `a` and `b`, whereas `a = a + [1]` modifies only `a`. – zvone May 23 '18 at 19:49
  • a=a+"ali" is an error because you can not concatenate list with a string. – Agniveer May 23 '18 at 19:53
  • @zvone It's really interesting. probably for you it's normal. but in my university, teacher said they are same. and I watched many videos about programming. and all of them said they are same. I am wondering one thing about this, i += 1 situation can be use instead of other in every position? or not? because i+=1 can creates a new object too. – Njx May 23 '18 at 19:54
  • @njx They are two separate operations which may or may not do the same thing, depending on the object (`i`). For built-in immutable objects, like `int` and `str`, they will probably do the same, because there is no way to modify the object. For mutable objects I would expect that they are different. That still does not explain why one accepts strings whereas the other does not, but I cannot give you a better answer for that part. To me it actually makes sense, but it could have been implemented differently. – zvone May 23 '18 at 20:00
  • 1
    @zvone - not quite. `__iadd__` and `__add__` both return objects. `list.__iadd__` returns itself while `int.__iadd__` returns a new object. So, `x = 1;x += 1` creates a new object. The objects themselves decide what they should do. – tdelaney May 23 '18 at 20:17
  • @tdelaney: Still not quite right. `int.__iadd__` doesn't exist at all, so `+=` falls back to `int.__add__`, which creates a new object. `list.__iadd__` exists, and returns the original, modified list. – user2357112 May 23 '18 at 20:41

3 Answers3

4

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.

Olivier Melançon
  • 21,584
  • 4
  • 41
  • 73
0

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("...").

hyper-neutrino
  • 5,272
  • 2
  • 29
  • 50
0
>>> 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']
s3n0
  • 596
  • 3
  • 14