Question

Does Python pass arguments to functions by reference or by value? I have heard that ints and chars are passed by value, but lists and strings are passed by reference.

But when I write-

def prepend(element,list):
    list = [element] + list

tryList = [1,2,3]
prepend(0,tryList)
print (tryList)

The expected output is (assuming that lists are passed by reference) is: [0,1,2,3]. But the actual output is: [1,2,3], which suggests that it is passed by value.

The main confusion arises when I write

def appendList(element,l):
    l.append(element)
tryList = [1,2,3]
appendList(0,l)
print (l)

output is: [1,2,3,0]

Was it helpful?

Solution 2

list = [element] + list creates a new list and overwrites the original value of, um, list. I doesn't add element to the existing list so it doesn't demonstrate pass by reference. It is equivalent to:

list2 = [element] + list
list = list2

The following demonstrates pass by reference by adding to the existing list instead of creating a new one.

def prepend(element, _list):
    _list.insert(0, element)

_try = [1,2,3]
prepend(0, _try)
print(_try)

UPDATE

It may be more clear if I add print statements that show how the variables change as the program executes. There are two versions of prepend, one that creates a new object and another that updates an existing object. The id() function returns a unique identifier for the object (in cpython, the memory address of the object).

def prepend_1(element, _list):
    print 'prepend_1 creates a new list, assigns it to _list and forgets the original'
    print '_list refers to the same object as _try -->', id(_list), _list
    _list = [element] + _list
    print '_list now refers to a different object -->', id(_list), _list

def prepend_2(element, _list):
    print 'prepend_2 updates the existing list'
    print '_list refers to the same object as _try -->', id(_list), _list
    _list.insert(0, element)
    print '_list still refers to the same object as _try -->', id(_list), _list

_try = [1,2,3]
print '_try is assigned -->', id(_try), _try
prepend_1(0, _try)
print '_try is the same object and is not updated -->', id(_try), _try
prepend_2(0, _try)
print '_try is the same object and is updated -->', id(_try), _try
print _try

When I run it, you can see how the objects relate to the variables that reference them

_try is assigned --> 18234472 [1, 2, 3]
prepend_1 creates a new list, assigns it to _list and forgets the original
_list refers to the same object as _try --> 18234472 [1, 2, 3]
_list now refers to --> 18372440 [0, 1, 2, 3]
_try is the same object and is not updated --> 18234472 [1, 2, 3]
prepend_2 updates the existing list
_list refers to the same object as _try --> 18234472 [1, 2, 3]
_list still refers to the same object as _try --> 18234472 [0, 1, 2, 3]
_try is the same object and is updated --> 18234472 [0, 1, 2, 3]
[0, 1, 2, 3]

OTHER TIPS

Python is PASS-BY-VALUE only.

Just like non-primitives in Java, all values in Python are references, i.e. pointers to objects. And just like in Java, they are assigned and passed by value. Always.

My definition is: If simple assignment (=) to a parameter has the same effect as simple assignment (=) to the passed variable in the calling scope, then it is pass-by-reference. If simple assignment (=) to a parameter has no effect on the passed variable in the calling scope, then it is pass-by-value. It is the latter in Java, Python, Ruby, Scheme, Go, C, JavaScript, Smalltalk, and many other languages.

"CALL BY OBJECT" This should answer your question. http://effbot.org/zone/call-by-object.html

It is not pass by value. Everything in python is pass by reference.

def prepend(element,list):
    list = [element] + list  # Here new memory is allocated for "list" ,
                              # note list is here a local variable. 

And please do not use 'list' as name of varible, it is a keyword for data type name.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top