# two - set difference python

## Difference between a-= b and a=a-b in Python (2)

I have recently applied
this
solution for averaging every N rows of matrix.
Although the solution works in general I had problems when applied to a 7x1 array. I have noticed that the problem is when using the
`-=`

operator.
To make a small example:

```
import numpy as np
a = np.array([1,2,3])
b = np.copy(a)
a[1:] -= a[:-1]
b[1:] = b[1:] - b[:-1]
print a
print b
```

which outputs:

```
[1 1 2]
[1 1 1]
```

So, in the case of an array
`a -= b`

produces a different result than
`a = a - b`

. I thought until now that these two ways are exactly the same. What is the difference?

How come the method I am mentioning for summing every N rows in a matrix is working e.g. for a 7x4 matrix but not for a 7x1 array?

Internally, the difference is that this:

`a[1:] -= a[:-1]`

is equivalent to this:

```
a[1:] = a[1:].__isub__(a[:-1])
a.__setitem__(slice(1, None, None), a.__getitem__(slice(1, None, None)).__isub__(a.__getitem__(slice(1, None, None)))
```

while this:

`b[1:] = b[1:] - b[:-1]`

maps to this:

```
b[1:] = b[1:].__sub__(b[:-1])
b.__setitem__(slice(1, None, None), b.__getitem__(slice(1, None, None)).__sub__(b.__getitem__(slice(1, None, None)))
```

In some cases,
`__sub__()`

and
`__isub__()`

work in a similar way. But mutable objects should mutate and return themselves when using
`__isub__()`

, while they should return a new object with
`__sub__()`

.

Applying slice operations on numpy objects creates views on them, so using them directly accesses the memory of the "original" object.

The docs say :

The idea behind augmented assignment in Python is that it isn't just an easier way to write the common practice of storing the result of a binary operation in its left-hand operand, but also a way for the left-hand operand in question to know that it should operate `on itself', rather than creating a modified copy of itself.

As a thumb rule, augmented substraction (
`x-=y`

) is
`x.__isub__(y)`

, for
**
IN
**
-place operation
**
IF
**
possible, when normal substraction (
`x = x-y`

) is
`x=x.__sub__(y)`

. On non mutable objects like integers it's equivalent. But for mutable ones like arrays or lists, as in your example, they can be very different things.