0

I have a question regarding the numpy subtraction assignment operator. When using the "-=" operator the referenced variable seems to be changed by the operation, which is not the case when the subtractor is substracted explicitly. Here is my MWE to illustrate this:

import numpy as np
np1 = np.array([1])
np2 = np1
np2 -= 2
print(np1)

np3 = np.array([1])
np4 = np3
np4 = np4 - 2
print(np3)

output:

[-1]

[1]

Why does the subtraction assignment operator behave in this way?

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
MPIchael
  • 176
  • 7
  • because augmented assignment operators conventionally work in-place. – juanpa.arrivillaga Mar 14 '23 at 22:23
  • In other words, `x = x + 1` is **not equivalent** to `x += 1`. Roughly speaking, the former is essentially `x = x.__add__(1)`, the latter is `x = x.__iadd__(1)` – juanpa.arrivillaga Mar 14 '23 at 22:24
  • It is probably good to read [the PEP that originally proposed adding these operators to the language back in the year 2000!](https://peps.python.org/pep-0203/) A quote: "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." – juanpa.arrivillaga Mar 14 '23 at 22:31

1 Answers1

1

This should help explain what is going on

import numpy as np
np1 = np.array([1])
np2 = np1
print(np1 is np2)
np2 -= 2
print(np1 is np2)
print(np1)

np3 = np.array([1])
np4 = np3
print(np3 is np4)
np4 = np4 - 2
print(np3 is np4)
print(np3)

Output:

True
True
[-1]
True
False
[1]

In the first case, np1 is changed by the operation because np2 is simply another name for the array named np1. In the second case, the operation makes a copy of the result and assigns it to np4 rather than changing np3.

Bill
  • 10,323
  • 10
  • 62
  • 85
  • 1
    Thank you for your answer! Is this difference in behaviour intended? In general, these two operations are equivalent in python, so the expectation would be the same for numpy arrays, wouldn't it? Is there some kind of operator overloading present for numpy data objects? – MPIchael Mar 14 '23 at 22:25
  • 1
    @MPIchael it is *absolutely* intended and *absolutly* you shoud not think of `x += whatever` and `x = x + whatever` as equivalent. They are not. – juanpa.arrivillaga Mar 14 '23 at 22:29
  • 1
    As an example of what @juanpa.arrivillaga is saying. Consider: `items1 = ['a', 'b', 'c']; items2 = items1; items2 += ['d', 'e']`. – Bill Mar 14 '23 at 22:31
  • 1
    @MPIchael read my comments in the question, and the linked duplicate. I also linked to the PEP where these operators were first proposed, so you can read about the motivations and the use-cases they were designed for – juanpa.arrivillaga Mar 14 '23 at 22:32
  • `np1` is a mutable object. Its value(s) can be changed in-place. `x=1;x+=2` works on a immutable number. – hpaulj Mar 14 '23 at 23:28