Call by value or reference?

March 15, 2018

When solving leetcode with python, I found some interesting things happening in python which confuse me whether python is passing value like Java or reference like c++. So I dive in to google for some answer in case someone have written something on this part. Indeed, Jeff Knupp wrote this blog which notify me that python does neither. It treats variable or arguments as a name which combine to an object. Talk is cheap, show me the code.

class Solution:
    def removeElement(self, nums, val):
        nums = nums[:val]
if __name__ == "__main__":
    solution = Solution()
    t1 = [3,2,2,3]
    val = 2
    solution.removeElement(t1, val)
    print(t1, end="\t")

Take a look at the above code, the result will be printed as follow:

[2, 2, 3, 3]

which means the t1 is not changed at all.

So we can definetely say that python is not passed by reference. However, does it mean variable is argument by value? Let us talk on the code again:

class Solution:
    def removeElement(self, nums, val):
        nums.append(val)
if __name__ == "__main__":
    solution = Solution()
    t1 = [3,2,2,3]
    val = 1
    solution.removeElement(t1, val)
    print(t1, end="\t")

This will actaully output [3, 2, 2, 3, 1] meaning the function indeed changed the value of the argument. That says argument is not passed by value either. Notice in this case nums is mutable. If nums is immutable like a tuple, then python can not modify the input either.

You might be upset about the above result but wait a sec, google tells me that python is actually passing argument as name. What does it mean? The following picture is equivalent to a, b = 2, a

After seeing this picture, everything suddenly make sense. Back to our case, you can imagine that a is t1, b is nums. When we re-assign value to b, we actually is just using b to name another new object which won’t change the actually value of what a is representing. However, when we modify the what b is representing for, a would be changed too. This tricky stuff is like a pointer actually.

Reference