0

I've been struggling with some operations over NumPy arrays and functions in a recent script. I've finally discovered what seems to be the error: NumPy __isub__.

Heres a example:

def test(apocalypse):
    apocalypse = apocalypse - 3
    return apocalypse

def test2(apocalypse):
    apocalypse -= 3
    return apocalypse

foo = np.array([1,2,3])
print(test(foo))
print(foo)

bar = np.array([1,2,3])
print(test2(bar))
print(bar)

Which results in:

[-2 -1  0]
[1 2 3]
[-2 -1  0]
[-2 -1  0]

Was it expected? Should -= change a global variable (same for +=)? I've tried with int and float instead of NumPy arrays and it worked as I expected.

Rodrigo
  • 5
  • 2
  • Yes, the difference wih `int` and `float` is that these are immutable values. – Willem Van Onsem Apr 07 '20 at 23:53
  • `ndarray` is mutable, so `arr -= 3` modifies `arr` itself. That's normal. `alist.append(3)` is another example that modifies a mutable object. – hpaulj Apr 08 '20 at 00:01
  • OMG, i didn't check if ```-=``` was mutable. Assignments always create a new reference, but -= is not an assignment, it is more a kind of "mutating method", right? – Rodrigo Apr 08 '20 at 00:12

1 Answers1

0

Posting an answer in case anybody needs more details than the hpaulj and Willem Van Onsem quick and good answers.

I'm supposing we already understand how mutable/immutable objects work. If not, here we have an answer about it, in a by reference vs by assignment context.

The problem I faced was due to the fact that isub is an in-place operator and it was used with a mutable object so the original variable passed by assignment to the test function has its object changed, having not to do with global variables as I supposed.

Note that as we could see, it's not because you have a mutable object that all operations will change the object in-place though. Example with id:

arr = np.array([1,2,3])
print(id(arr))    # prints 139838225358560
arr += 3 
print(arr)        # prints [4 5 6]
print(id(arr))    # prints 139838225358560
arr = arr + 3
print(arr)        # prints [7 8 9]
print(id(arr))    # prints 139838016018832

The in-place operator += performs the change of the object arr while the assignment = creates a new one. The same goes in my question with apocalypse -= 3 and apocalypse = apocalypse - 3, respectively.

Python documentation has a short and good explanation of in-place operators with a list of them.

Rodrigo
  • 5
  • 2