Search code examples
pythonlistfunctionpass-by-referencepass-by-value

Why did this python list appear to get passed "by value"?


I defined the following function:

def myFunction(a):
  print(f'In function, initial a = {a}, {id(a)}, {type(a)}')
  a = a*10
  print(f'In function, final a = {a}, {id(a)}, {type(a)}')
  return a

When I try calling it like so:

a_list_var = [3]
print(f'In main script, initial a_list_var = {a_list_var}, {id(a_list_var)}, {type(a_list_var)}')
myFunction(a_list_var)
print(f'In main script, final a_list_var = {a_list_var}, {id(a_list_var)}, {type(a_list_var)}')

I get this result:

In main script, initial a_list_var = [3], 139940245107776, <class 'list'>
In function, initial a = [3], 139940245107776, <class 'list'>
In function, final a = [3, 3, 3, 3, 3, 3, 3, 3, 3, 3], 139940654735936, <class 'list'>
In main script, final a_list_var = [3], 139940245107776, <class 'list'>

As far as I understand, function arguments in Python get passed "by reference". Since lists are mutable objects, I expected a_list_var to get altered in-place after calling myFunction(). But in this case, looking at the ids of a_list_var and a, it seems like a_list_var got passed "by value". Why?


Solution

  • Your function, myFunction, returns the repetition of the list argument a. However, you did not assign the returned list to a_list_var. You can try this:

    def myFunction(a):
      print(f'In function, initial a = {a}, {id(a)}, {type(a)}')
      a *= 10 # This is a short for "a = a * 10"
      print(f'In function, final a = {a}, {id(a)}, {type(a)}')
      return a
    a_list_var = [3]
    print(f'In main script, initial a_list_var = {a_list_var}, {id(a_list_var)}, {type(a_list_var)}')
    a_list_var = myFunction(a_list_var)
    print(f'In main script, final a_list_var = {a_list_var}, {id(a_list_var)}, {type(a_list_var)}')
    

    What I changed is, I assigned the returned list to the list a_list_var, which results in the following output:

    In main script, initial a_list_var = [3], 22569753494784, <class 'list'>
    In function, initial a = [3], 22569753494784, <class 'list'>
    In function, final a = [3, 3, 3, 3, 3, 3, 3, 3, 3, 3], 22569752701824, <class 'list'>
    In main script, final a_list_var = [3, 3, 3, 3, 3, 3, 3, 3, 3, 3], 22569752701824, <class 'list'>