0

If a variable is used as an argument of a function, then all modifications done inside the function with the argument apply to the variable. This is normal and expected, but in many cases undesirable. What is the best practice to prevent this behaviour? Example:

import numpy as np
def func(A):
    for ind in range(A.shape[0]):  
        A[ind] = A[ind]+1
    return A

A = np.array([1, 2, 3])
NewA = func(A)
print(A)
print(NewA)

Out: [2, 3, 4]
Out: [2, 3, 4]

While we want:

Out: [1, 2, 3]
Out: [2, 3, 4]

So far I came up only with two ideas.

Method one: obviously, pass a copy of a variable:

A = np.array([1, 2, 3])
NewA = func(A.copy())
print(A)
print(NewA)
Out: [1, 2, 3]
Out: [2, 3, 4]

Returns what expected but becomes really annoying when one have a function of 5 arguments: it is just too long to type .copy() every time.

Method two: Modify the function body

def func(A):
    B = A.copy()
    for ind in range(B.shape[0]):  
        B[ind] = B[ind]+1
    return B

This is equally annoying and requires modification of functions. Any other ideas?

Community
  • 1
  • 1
kudich
  • 1
  • 1
  • This shouldn't be surprising. Please read [this excellent blog post on python variables and values](https://nedbatchelder.com/text/names.html). The key point you seem to be missing is you *are creating a new variable with function arguments*, but that new variable refers to the *same object*. So, *variables* aren't modified, objects are. – juanpa.arrivillaga Mar 10 '18 at 22:41
  • Thanks everyone for the responses. I've modified the question to highlight the difference between the proposed answer. – kudich Mar 11 '18 at 02:11

1 Answers1

-2

This is due to the type of the parameter. If the parameter is an immutable object such as an int or a string, it acts like call by value. If it is a mutatable object such as np.darray, it acts like call by reference.

  • Absolutely incorrect. The evaluation strategy is always the same for Python, regardless of the object's type. Note, both `int` and `str` **are objects**. Everything in Python is an object. – juanpa.arrivillaga Mar 10 '18 at 22:45
  • Again, mutable and immutable objects **have the same evaluation strategy**, which is *neither* call by value nor call by reference. You simply cannot mutate immutable objects, so you cannot ever see any changes to them. – juanpa.arrivillaga Mar 10 '18 at 22:51