Is i = i + n truly the same as i += n? [duplicate] Is i = i + n truly the same as i += n? [duplicate] python python

Is i = i + n truly the same as i += n? [duplicate]


They don't have to be the same.

Using the + operator calls the method __add__ while using the += operator calls __iadd__. It is completely up to the object in question what happens when one of these methods is called.

If you use x += y but x does not provide an __iadd__ method (or the method returns NotImplemented), __add__ is used as a fallback, meaning that x = x + y happens.

In the case of lists, using l += iterable actually extends the list l with the elements of iterable. In your case, every character from the string (which is an iterable) is appended during the extend operation.

Demo 1: using __iadd__

>>> l = []>>> l += 'table'>>> l['t', 'a', 'b', 'l', 'e']

Demo 2: using extend does the same

>>> l = []>>> l.extend('table')>>> l['t', 'a', 'b', 'l', 'e']

Demo 3: adding a list and a string raises a TypeError.

>>> l = []>>> l = l + 'table'[...]TypeError: can only concatenate list (not "str") to list

Not using += gives you the TypeError here because only __iadd__ implements the extending behavior.

Demo 4: common pitfall: += does not build a new list. We can confirm this by checking for equal object identities with the is operator.

>>> l = []>>> l_ref = l # another name for l, no data is copied here>>> l += [1, 2, 3] # uses __iadd__, mutates l in-place>>> l is l_ref # confirm that l and l_ref are names for the same objectTrue>>> l[1, 2, 3]>>> l_ref # mutations are seen across all names[1, 2, 3]

However, the l = l + iterable syntax does build a new list.

>>> l = []>>> l_ref = l # another name for l, no data is copied here>>> l = l + [1, 2, 3] # uses __add__, builds new list and reassigns name l>>> l is l_ref # confirm that l and l_ref are names for different objectsFalse>>> l[1, 2, 3]>>> l_ref[]

In some cases, this can produce subtle bugs, because += mutates the original list, while
l = l + iterable builds a new list and reassigns the name l.

BONUS

Ned Batchelder's challenge to find this in the docs


No.

7.2.1. Augmented assignment statements:

An augmented assignment expression like x += 1 can be rewritten as x = x + 1 to achieve a similar, but not exactly equal effect. In the augmented version, x is only evaluated once. Also, when possible, the actual operation is performed in-place, meaning that rather than creating a new object and assigning that to the target, the old object is modified instead.


If in the second case, you wrap a list around n to avoid errors:

for n in l:    i = i + [n]print(i)

you get

['table']

So they are different operations.