Abz Rockers
Abz Rockers

Reputation: 338

Python call by reference issue

As what I have understand on python, when you pass a variable on a function parameter it is already reference to the original variable. On my implementation when I try to equate a variable that I pass on the function it resulted empty list.

This is my code:

#on the main -------------
temp_obj = []
obj = [
    {'name':'a1', 'level':0},
    {'name':'a2', 'level':0},
    {'name':'a3', 'level':1},
    {'name':'a4', 'level':1},
    {'name':'a5', 'level':2},
    {'name':'a6', 'level':2},
]

the_result = myFunction(obj, temp_obj)

print(temp_obj)
#above print would result to an empty list
#this is my problem

#end of main body -------------


def myFunction(obj, new_temp_obj):
     inside_list = []
     for x in obj[:]:
         if x['level'] == 0:
              inside_list.append(x)
              obj.remove(x) #removing the element that was added to the inside_list

     new_temp_obj = obj[:] #copying the remaining element 

     print(new_temp_obj) 
     # the above print would result to
     #[{'name': 'a3', 'level': 1}, {'name': 'a4', 'level': 1}, {'name': 'a5', 'level': 2}, {'name': 'a6', 'level': 2}]

     return inside_list

Am I missing something or did I misunderstand the idea of python call by reference?

Upvotes: 1

Views: 591

Answers (2)

pushkin
pushkin

Reputation: 10227

Python is not pass-by-reference. It is pass-by-object.

Consider the following two functions:

def f(mylist):
    mylist = []

def g(mylist):
    mylist.append(1)

Now let's say I call them.

mylist = [1]
f(mylist)
print(mylist)

mylist = [1] # reset the list
g(mylist)
print(mylist)

What would the output be?

If Python were pass-by-value, the functions would take a copy of the list, so modifying it would not affect the original list once you return out of the function. So in both cases, you would be printing the original list, [1].

If Python were pass-by-reference, the functions would accept a reference to the object and modifying it would modify the actual object that the reference references, so the first output would be [] and the second, [1,2].

If you run this example, you will find that the first output is [1] (the list if unaffected) and second output is [1,2] (the list is affected).

O_O

When you do new_temp_obj = obj[:], Python is constructing a new object obj[:] and giving it the name new_temp_obj.

If you were to append, Python would look for the thing called new_temp_obj and add elements to it. The argument you passed in tells it where to look for the list.

You are creating a totally new object at a totally new location in memory and simply giving it the same name,new_temp_obj

Upvotes: 1

Yu Hao
Yu Hao

Reputation: 122433

new_temp_obj = obj[:] #copying the remaining element 

This would make new_temp_obj reference to another new list object. You could use id to see that its id changes with this assignment.

Change it to:

new_temp_obj[:] = obj[:]

You'll see your expected result.

Upvotes: 1

Related Questions