0

I can change it undirectly like this:

def myFun(x):
for i in range(len(x)):
    x[i] +=2

access to items then change them

lst = [10, 11, 12, 13, 14, 15]
myFun(lst)
print(lst)

output: [12, 13, 14, 15, 16, 17]

but can not this:

def myFun(x):
 x = [20, 30, 40]
lst = [10, 11, 12, 13, 14, 15]
myFun(lst)
print(lst)

output: [10, 11, 12, 13, 14, 15]
NhanChau
  • 3
  • 2
  • `lst = [10, 11, 12, 13, 14, 15]` **never** changes the list. It *creates a new list* and assigns it to the local variable `lst`. – juanpa.arrivillaga May 30 '21 at 05:07
  • Read the following: https://nedbatchelder.com/text/names.html – juanpa.arrivillaga May 30 '21 at 05:08
  • Also, I'm not sure what you even mean by "undirectly", `x[i] +=2` *directly* changes the list – juanpa.arrivillaga May 30 '21 at 05:09
  • I think what he mean that the reference of the list is being pass. @juanpa.arrivillaga Hence we can modify the list but cannot assign something new to that reference. – Yoshikage Kira May 30 '21 at 05:11
  • @Goion well, then why would `x = [20, 30, 40]` be direct? – juanpa.arrivillaga May 30 '21 at 05:12
  • I assume they are thinking as if python is c. In c this should be possible with having access to pointer. But in python no. @juanpa.arrivillaga – Yoshikage Kira May 30 '21 at 05:23
  • @Goion *python doesn't have pointers*. Python uses *neither* call by value *nor* call by reference as an evaluation strategy. I would avoid the Java way of explaining things, because it is very confused and only kind of makes sense in Java because there is an explicit concept of "primitive" types and "referenec" types. Python isn't Java, it's purely object oriented – juanpa.arrivillaga May 30 '21 at 05:35
  • Yes, that is what I said. Python is call by object reference which is also the case in java when we pass objects (reference type). Primitive types are strictly pass by value. @juanpa.arrivillaga. Nvm I deleted it since it might confuse the op even more. – Yoshikage Kira May 30 '21 at 05:38
  • @juanpa.arrivillaga thank for your link, it's very helpful – NhanChau Jun 01 '21 at 09:04

2 Answers2

1

You would like to google "python pass by assignment" for example.

When you pass an argument to a function, the passed object is assigned to the internal variable of the function. For example, in

def myFun(x):
    for i in range(len(x)):
        x[i] += 2

lst = [10, 11, 12, 13, 14, 15]
myFun(lst)

you are first bounding a name lst to an object [10, 11, ..., 15] (outside the function). Then you pass this to the function, so that inside the function, x refers to the same object which lst was refering to. So you have two names (lst outside the function and x inside the function) for the same object. When the function does x[i] += 2, it goes to this object (i.e., the list) and does the work. It does not care whether it is called x or lst; it just increment the i-th element of that specific object. Since x and lst are just different names of the object, after the function call, lst refers to that (modified) object. x is not available outside the function; it is just discarded. But you still have the name lst, which still points to the (modified) object.

Now in

def myFun(x):
    x = [20, 30, 40]
lst = [10, 11, 12, 13, 14, 15]
myFun(lst)

The procedure is the same; x first refers to the object lst was refering to: the object [10, ..., 15]. But then you say "now x, listen to me. Don't point to that object. You now refer to a newly created list [20, 30, 40]." This is what the assignment x = ... does. Now x and lst points to totally different objects. As above, x is discarded, and so is the object it refered to. lst still points to the object it has been pointing, which was not modified by the function.

j1-lee
  • 13,764
  • 3
  • 14
  • 26
0

The array you are passing in the first method is changed because, you are changing the object which is passed as a refence through the argument, you are iterating through indexes of the array which translate to the actual memory address of each item in the list.

However the second function varies, because you are creating a new list inside of the method and attributing it to x, the new array is a total new object, it is not pointing to your array anymore. Instead it is pointing to a total unrelated and new array.

By the end of the method x which is unused since it is scope based, is discard and your list remains with the same size and items.

richard_ba
  • 13
  • 1
  • 3