# What is the difference between i = i + 1 and i += 1 in a 'for' loop?

I found out a curious thing today and was wondering if somebody could shed some light into what the difference is here?

```    import numpy as np

A = np.arange(12).reshape(4,3)
for a in A:
a = a + 1

B = np.arange(12).reshape(4,3)
for b in B:
b += 1
```

After running each `for` loop, `A` has not changed, but `B` has had one added to each element. I actually use the `B` version to write to a initialized NumPy array within a `for` loop.

The difference is that one modifies the data-structure itself (in-place operation) `b += 1` while the other just reassigns the variable `a = a + 1`.

Just for completeness:

`x += y` is not always doing an in-place operation, there are (at least) three exceptions:

• If `x` doesn't implement an `__iadd__` method then the `x += y` statement is just a shorthand for `x = x + y`. This would be the case if `x` was something like an `int`.

• If `__iadd__` returns `NotImplemented`, Python falls back to `x = x + y`.

• The `__iadd__` method could theoretically be implemented to not work in place. It'd be really weird to do that, though.

As it happens your `b`s are `numpy.ndarray`s which implements `__iadd__` and return itself so your second loop modifies the original array in-place.

You can read more on this in the Python documentation of "Emulating Numeric Types".

These [`__i*__`] methods are called to implement the augmented arithmetic assignments (`+=`, `-=`, `*=`, `@=`, `/=`, `//=`, `%=`, `**=`, `<<=`, `>>=`, `&=`, `^=`, `|=`). These methods should attempt to do the operation in-place (modifying self) and return the result (which could be, but does not have to be, self). If a specific method is not defined, the augmented assignment falls back to the normal methods. For instance, if x is an instance of a class with an `__iadd__()` method, `x += y` is equivalent to `x = x.__iadd__(y)` . Otherwise, `x.__add__(y)` and `y.__radd__(x)` are considered, as with the evaluation of `x + y`. In certain situations, augmented assignment can result in unexpected errors (see Why does `a_tuple[i] += ["item"]` raise an exception when the addition works?), but this behavior is in fact part of the data model.

From: stackoverflow.com/q/41446833