I am wondering why when changing values to a list by calling a function, there is such a difference in the following two scenarios (assign new value to list v.s. to list[:]). I guess it has something to do with call-by-value/call-by-reference.
Code
def rotate1(nums, k) -> None:
nums = nums[-k:]+nums[:-k]
print(f"In rotate1: {nums}")
def rotate2(nums, k) -> None:
nums[:] = nums[-k:]+nums[:-k]
print(f"In rotate2: {nums}")
ls1 = [1,2,3,4]
rotate1(ls1, 2)
print(f"Outside rotate1: {ls1}\n")
ls2 = [1,2,3,4]
rotate2(ls2, 2)
print(f"Outside rotate2: {ls2}\n")
Output
In rotate1: [3, 4, 1, 2]
Outside rotate1: [1, 2, 3, 4]
In rotate2: [3, 4, 1, 2]
Outside rotate2: [3, 4, 1, 2]
ls1 value does not change after calling rotate1; whereas ls2 value changes after calling rotate2.
The same problem is explained exactly in this page Is Python pass-by-reference or pass-by-value?
As we know, in Python, “Object references are passed by value”.
In both rotate methods, the nums
creates a new variable to point to object [1,2,3,4]. The difference is:
nums = nums[-k:]+nums[:-k]
causes nums
to point to a new object.nums[:] = nums[-k:]+nums[:-k]
causes the object pointed by nums
changed.So, outside the methods, only the rotate2
really changes the object of ls2
.