0

According to my textbook, in Python, all parameters behave like local variables and their effect is as though they are passed by value. So should b in my code remain the same after passing into the function like a?

enter image description here

I expected b to be [0,0,0,0,0] at the end.

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
TFR
  • 131
  • 1
  • 5
  • Possible duplicate of [How do I pass a variable by reference?](https://stackoverflow.com/questions/986006/how-do-i-pass-a-variable-by-reference) – jonrsharpe Jul 12 '19 at 08:15
  • Your textbook is wrong; parameters are passed by object reference in Python. – jonrsharpe Jul 12 '19 at 08:17
  • @jonrsharpe that statement is technically not correct. parameters are passed by *assignment* in python. (And in terms of by value/reference, they're actually passed by value, but the issue is all python variables can be thought of as 1-level pointers. But we shouldn't really bring those into discussion in python) – Paritosh Singh Jul 12 '19 at 08:44
  • @ParitoshSingh same thing, the object reference *is* the value you refer to – jonrsharpe Jul 12 '19 at 08:45
  • aye, but it's easily misinterpreted by someone not familiar with the nitty-gritty details, and i find it easier to just talk about pass by assignment while introducing someone to python parameters. – Paritosh Singh Jul 12 '19 at 08:46
  • @ParitoshSingh Does passing by assignment mean that the parameter in a function is always assigned to the argument input first? For example, if the input is 2, then the x in my function is assigned to 2, and if the input is a, the content of a which is 2 is assigned to x? – TFR Jul 12 '19 at 09:43
  • @田丰睿 yep, that's correct. All behaviours that you see when passing to a function, you can also see when just assigning to x directly. There is no "magic" happening when you pass to a function, it's the same as writing `x = a`. Now, if you write `x[0] = 1`, both `x` and `a` will reflect the change because they refer to the same underlying list object. – Paritosh Singh Jul 12 '19 at 10:25

2 Answers2

1

You can copy list 'x' before assigning its first element to 1.

>>> def B(x):
...     x[0] = 1
...     print(x)
...
>>> x = [0, 0, 0, 0]
>>> B(x)
[1, 0, 0, 0]
>>> x
[1, 0, 0, 0]
>>>
>>> def B2(x):
...     x = x.copy()
...     x[0] = 1
...     print(x)
...
>>> x = [0, 0, 0, 0]
>>> B2(x)
[1, 0, 0, 0]
>>> x
[0, 0, 0, 0]

Because python parameter is passed by object reference, and list is a mutable object, once you pass a list into function and change its element, the original one would be change too.

But if you use 'x = x.copy()' before assigning, 'x' would not be the same object to the original one, so any change to 'x' in the function would not affect the 'x' in the main scope.

Chun-Ye Lu
  • 343
  • 1
  • 2
  • 10
0
def A(x):
    x = 10
    print (x)

a= 2
A(a) # 10
print(a) # 2 a is still referring to the same object


def B(x):
    x[0] = 1
    print (x)

b = [0,0,0,0,0]
B(b) # [1, 0, 0, 0, 0]
print (b) # [1, 0, 0, 0, 0] b changed!

Passing Immutable Objects

We have the variable a referring to the object with value 2. When we pass a to A(x), the function has the local variable x referenced to the same object. Since integer is immutable, by definition we are not able to modify the objects value to 10 in place, all the time, the variable a continues to refer to the object with the value 2, what explains why the value of a doesnt not change after calling.

NOTE: we can still "modify" immutable objects by capturing the return of the function.

def A(x):
    x = 10
    return (x)

a= 2
a = A(a)
print(a) # 10 a now refers to the new object created by the function

By assigning the return value of the function to a, we have reassigned a to refer to the new object with the value 10 created in the function. Note the object a initially referred to never change — it is still 2 — but by having a point to a new object created by the function, we are able to “modify” the value of a.

Passing Mutable Objects

The B(b) function generates a different result when we passing a mutable object.

The code b = [0,0,0,0,0] has the variable b refer to the list object containing references to three immutable objects: integer 0, 0, 0, 0 and 0.

As usual, when we pass b to B(), the function has the local variable x refer to the same object as b. The x[0] = 1 modifies the list in place, since list is mutable. Since no new object is created and the change occurred in place of the object, when we print b, we get the modified list.

ncica
  • 7,015
  • 1
  • 15
  • 37
  • At the beginning of the function, b is assigned to x? So x and b now refers to the same list, and since the 0th element in the list is changed by the code x[0] = 1, b is also changed? And at the begining of A(x), a is assigned to x first and both now refers to the integer 2; since only x is changed by the code x = 10, a remains the same? – TFR Jul 12 '19 at 10:12
  • I tried the code... Sorry I don't know how to type my code properly in comment.. >>> def C(x): x = [0,0,0,0] print(x) >>> c = [1,1,1,1] >>> C(c) [0, 0, 0, 0] >>> c [1, 1, 1, 1] And it seems clear now – TFR Jul 12 '19 at 10:15
  • try to change x[0] in your function C and you will see the diference – ncica Jul 12 '19 at 10:20