How do numpy's in-place operations (e.g. `+=`) work?
numpy, python
Solution
The first thing you need to realise is that `a += x` doesn't map exactly to `a.__iadd__(x)`, instead it maps to `a = a.__iadd__(x)`. Notice that the documentation specifically says that in-place operators return their result, and this doesn't have to be `self` (although in practice, it usually is). This means `a[i] += x` trivially maps to:
a.__setitem__(i, a.__getitem__(i).__iadd__(x))
So, the addition technically happens in-place, but only on a temporary object. There is still potentially one less temporary object created than if it called `__add__`, though.
Problem
The basic question is: What happens under the hood when doing: `a[i] += b`? Given the following: ``` import numpy as np a = np.arange(4) i = a > 0 i = array([False, True, True, True], dtype=bool) ``` I understand that: - `a[i] = x` is the same as `a.__setitem__(i, x)`, which assigns directly to the items indicated by `i` - `a += x` is the same as `a.__iadd__(x)`, which does the addition in place But what happens when I do: ``` a[i] += x ``` Specifically: - Is this the same as `a[i] = a[i] + x`? (which is not an in-place operation) - Does it make a difference in this case if `i` is: - an `int` index, or - an `ndarray`, or - a `slice` object Background The reason I started delving into this is that I encountered a non-intuitive behavior when working with duplicate indices: ``` a = np.zeros(4) x = np.arange(4) indices = np.zeros(4,dtype=np.int) # duplicate indices a[indices] += x a = array([ 3., 0., 0., 0.]) ``` More interesting stuff about duplicate indices in this question.