1

I have a hard time to understand the python reference model

def changer(a,b):
    a = 2
    b[0] = 'spam'  
X = 1
L = [1,2] 
changer(X,L)  
X,L
(1,['spam',2])

here comes my question, for assignment b[0] = 'spam' : I want to know how python modify the mutable object in this way(instead of create a new string objects and link the variable b to that object which will not affect the original object pointed by L)

thanks

karthikr
  • 97,368
  • 26
  • 197
  • 188
  • 1
    This will help you understand: http://robertheaton.com/2014/02/09/pythons-pass-by-object-reference-as-explained-by-philip-k-dick/ – DevLounge Oct 28 '14 at 19:14
  • What exactly is confusing you? What did you expect to happen instead? – jonrsharpe Oct 28 '14 at 19:27
  • Have you seen http://stackoverflow.com/questions/986006/how-do-i-pass-a-variable-by-reference? Is there something there that is unclear? – Mark Ransom Oct 28 '14 at 19:34
  • @Apero: That explanation tries to be cute and look simple, but I actually find it kind of confusing (maybe because I'm not German?). This one is much better: http://nedbatchelder.com/text/names.html – John Y Oct 28 '14 at 19:37

3 Answers3

2

a and b are both references to objects.

When you reassign a you change which object a is referencing.

When you reassign b[0] you are reassigning another reference contained within b. b itself still references the same list object that it did originally, which is also the list that was passed into the changer function.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
  • what if I change the assignment to `b = [3,4]` ; it will still reassign references contained within `b`? can i make it this way: a variable which points to a mutable object contain several references within it ? – SuperZhuoli Oct 28 '14 at 20:00
  • @SuperZhuoli if you do `b = [3,4]` you are reassigning `b` to a new list object, which contains two additional references to the objects `3` and `4`. – Mark Ransom Oct 28 '14 at 20:13
  • Ok got it . when i print out `L`; i will get `[1,2]` thank you:) – SuperZhuoli Oct 28 '14 at 20:23
0

Variables name are pointers to a special memory address ,so when you pass L and X to function the function does not create a new address with a,b just changed the labels !, so any changes on those actually change the value of that part of memory that X,L point to. So for refuse that you can use copy module :

>>> from copy import copy
>>> def changer(a,b):
...     i = copy(a)
...     j = copy(b)
...     i = 2
...     j[0] = 'spam'
... 
>>> X = 1
>>> L = [1,2] 
>>> changer(X,L) 
>>> X,L
(1, [1, 2])
Mazdak
  • 105,000
  • 18
  • 159
  • 188
0

In Python, lists are mutable, and integers are immutable. This means that Python will never actually change the value of an integer stored in memory, it creates a new integer and points the variable at the new one.

The reason for this is to make Python's dynamic typing work. Unlike most languages, you can create a variable and store an int in it, then immediately store a string in it, or a float, etc.

MyVariable = 10     # This creates an integer and points MyVariable at it.
MyVariable = "hi"   # Created a new string and MyVariable now points to that.
MyVariable = 30     # Created a new integer, and updated the pointer

So this is what happens in your code:

MyVar = 1   # An integer is created and MyVar points to it.

def Increase(num):
   num = num + 1   #A new integer is created, the temp variable num points at it.

Increase(MyVar)
print(MyVar)    # MyVar still points to the original integer

This is a 'feature' of dynamically typed languages ;)

Vega_KH
  • 1
  • 2