Mohideen bin Mohammed
Mohideen bin Mohammed

Reputation: 20137

Python: Expression returns Different Response a=a+1 vs a+=1

Note: I know python is strongly typed and we wont concatenate 2 different types. but accidentally i have tried,

I got different result,

a = []
>>>a=a+1 #it gives me expected concatenate error
TypeError: can only concatenate list (not "int") to list


>>>a+=1 #but this wasn't
TypeError: 'int' object is not iterable

Upvotes: 0

Views: 160

Answers (3)

Devesh Kumar Singh
Devesh Kumar Singh

Reputation: 20490

From what I gather while doing experimentation is that.

  1. a = a + 1 is concatenating a list and an integer, but as we know + operator or concatenation requires two lists, hence the error we get is TypeError: can only concatenate list (not "range") to list, as we can see below
In [43]: [] + 1                                                                 
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-43-67dee89361ae> in <module>
----> 1 [] + 1

TypeError: can only concatenate list (not "int") to list
In [47]: [] + []                                                                
Out[47]: []
  1. In a += 1, we internally call a.extend(1) as per the docs: https://docs.python.org/3/library/stdtypes.html#mutable-sequence-types

s.extend(t) or s += t .
extends s with the contents of t (for the most part the same as s[len(s):len(s)] = t)

Also from the docs at: https://docs.python.org/3/tutorial/datastructures.html

list.extend(iterable)
Extend the list by appending all the items from the iterable. Equivalent to a[len(a):] = iterable.

So 1 is being treated as an iterable, but since int is not an iterable, we get the error TypeError: 'int' object is not iterable as we can see below

In [49]: a = []                                                                 

In [50]: a.extend(1)                                                            
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-50-4671950943e4> in <module>
----> 1 a.extend(1)

TypeError: 'int' object is not iterable

Upvotes: 2

JohanL
JohanL

Reputation: 6891

As stated the two operators do not map to the same magic function. And the two have different implementations. This has some interesting consequences. the normal plus (+ or __add__) expects another list to concatenate whereas in-place add (+= or __iadd__) is more allowing and can take any iterator and make it into a list before adding:

a = []
a = a + range(2)
TypeError: can only concatenate list (not "range") to list

a += range(2)
[0, 1]

I don't know why this is though.

Upvotes: 1

Daniel Chang
Daniel Chang

Reputation: 100

This is because operator + and operator += is not same magic function implement in list class.

__iadd__() ## Map to += Operator
__add__() ## Map to + Operator


That means you trigger different magic function of list object.

Upvotes: 2

Related Questions