1

I'm new to Python. From my friends, I learned that in python, parameter passing to a function is similar to call-by-reference in C++. But after some testing with NumPy, I saw some behaviors I cannot easily understand.

As an example, I made the following code.

#!/usr/bin/python

import numpy as np

def InitArray(x):
  x = np.arange(0, 5)

def ChangeValue(x):
  x[2] = 4

def main():
  x = np.array([1, 2, 3]) 
  print x
  InitArray(x)
  print x
  ChangeValue(x)
  print x

if __name__ == "__main__":
  main()

My expectation is after calling InitArray, the array 'x' should have changed to np.array([0, 1, 2, 3, 4]), but it turns out that it's not.

But when I call ChangeValue(x), the value is actually changed. So, the following is the result.

[1 2 3]
[1 2 3]
[1 2 4]

What I don't understand is why the value didn't become [0, 1, 2, 3, 4] after calling InitArray?

chanwcom
  • 4,420
  • 8
  • 37
  • 49
  • possible duplicate of [In Python, why can a function modify some arguments as perceived by the caller, but not others?](http://stackoverflow.com/questions/575196/in-python-why-can-a-function-modify-some-arguments-as-perceived-by-the-caller) – Joel Sep 20 '15 at 17:14

2 Answers2

3

I always think of it like pass-by-reference, but assignment in Python is not like assignment in other languages, either. It is merely binding a reference together with an object. But that reference can be unbound from that object and bound to a different one.

When you do:

def InitArray(x):
  x = np.arange(0, 5)

You are rebinding the local variable x to a different value. But you could have mutated it. Let me give you a non-numpy example:

>>> def foo(x):
...     x[3] = 4
...     x = [5, 5, 5]
... 
>>> x = [0] * 20
>>> x
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
>>> foo(x)
>>> x
[0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

The rebinding operator is similar to changing what a pointer points to in C.

Patrick Maupin
  • 8,024
  • 2
  • 23
  • 42
0

In ChangeValue you are accessing x at a specific point in memory. Whereas with InitArray you are essentially destroying x at the local scope and reassigning it within the function and then not returning the modified x.

postelrich
  • 3,274
  • 5
  • 38
  • 65