0

I have two codes for passing parameters to a function in Python. 1-

def changeme( mylist ):
   mylist.append([1,2,3,4]);
   print "Values inside the function: ", mylist
   return

mylist = [10,20,30];
changeme( mylist );
print "Values outside the function: ", mylist

2-

def changeme( mylist ):
   mylist = [1,2,3,4]; 
   print "Values inside the function: ", mylist
   return

mylist = [10,20,30];
changeme( mylist );
print "Values outside the function: ", mylist

Why in the first code mylist is passed by reference, and in second code it is passed by value?

programmingIsFun
  • 1,057
  • 2
  • 11
  • 20
  • 2
    They are both passed the same. The difference is what you are doing with the name after it's been passed. – Ned Batchelder Aug 15 '12 at 18:01
  • mylist is always passed as reference. –  Aug 15 '12 at 18:01
  • 1
    related: [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) – jfs Aug 15 '12 at 18:02
  • Wow, I really hate the "Python doesn't have variables" meme... At the very least, say, "Python doesn't have variables that work the same as C variables." A better description is, "In C, variables are containers. In Python, variables are labels." – Ned Batchelder Aug 15 '12 at 18:25
  • @Ned: Neither my answer nor the page I've linked has this quote. Instead there is: *«Although we commonly refer to "variables" even in Python (because it's common terminology), we really mean "names" or "identifiers". In Python, "variables" are nametags for values, not labelled boxes.»* which largely agrees with you. The specific terminology used by the language reference might be helpful when trouble-shooting a problem that is specific to how naming, binding works in Python. – jfs Oct 28 '12 at 23:50

5 Answers5

3

In the first example you append information to the list passed in. In the second example you reassign the local value of mylist before returning. The two are not doing the same things.

g.d.d.c
  • 46,865
  • 9
  • 101
  • 111
2

You need to realize that assignment in python does not operate on the object that is on the left hand side. Assignment creates a new reference to the object on the right hand side and stores that reference in the name on the left hand side. So, in your 1st example you mutate the list which you input and you see that change later. In the 2nd example, inside your function you create a new reference to a list (which is created on the right hand side) and bind that to the local (to the function) variable mylist. Therefore mylist no longer references the object which you input to the function.

mgilson
  • 300,191
  • 65
  • 633
  • 696
1

It's because you assigned mylist to some other object in function 2:

In python if you pass a mutable object to a function then it is called passed by reference and if you pass a immutable object then it is called pass by value.

mylist = [1,2,3,4]


def changeme( mylist ):
   print (id(mylist))  #prints 180902348

   #at this point the local variable mylist points to [10,20,30] 
   mylist = [1,2,3,4];  #this reassignment changes the local mylist, 

   #now local mylist points to [1,2,3,4], while global mylist still points to [10,20,30] 
   print (id(mylist)) #prints 180938508 #it means both are different objects now 

   print ("Values inside the function: ", mylist)
   return

mylist = [10,20,30];
changeme( mylist );
print ("Values outside the function: ", mylist)

first one:

def changeme( mylist ):
   print (id(mylist))      #prints 180902348

   mylist.append([1,2,3,4]);  #by this it mean [10,20,30].append([1,2,3,4])
   #mylist is just a label pointing to [10,20,30]
   print (id(mylist))       #prints 180902348  , both point to same object
   print ("Values inside the function: ", mylist)
   return

mylist = [10,20,30];
changeme( mylist );
print ("Values outside the function: ", mylist)
Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504
1

There's a difference between modifying an object and reassigning a name to a different object. A simple change to the code and it works consistently because now it's modifying the original object:

def changeme( mylist ):
   mylist[:] = [1,2,3,4]; 
   print "Values inside the function: ", mylist

P.S. There's no need for a return at the end of a function unless you're returning a value.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
-1

Python has pass by value semantics. Always. Objects are not values in Python. All values in the language are references (a.k.a. pointers). Objects are always manipulated through references. People come up with different names for this, but whatever they call it, what they are describing is semantically equivalent to pass by value of object references.

Whenever you pass or assign, the value (the reference) is copied. That means a called function has its own copy of the argument (which is a reference). Thus assigning to this variable has no effect on the caller. Never.

In your first code, you are not assigning to the parameter. Instead, you are calling a method through the reference on the object it points to. This method modifies the object. So of course anyone else who has a reference that points to the same object will see it.

newacct
  • 119,665
  • 29
  • 163
  • 224