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.
CodePudding user response:
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]
causesnums
to point to a new object.nums[:] = nums[-k:] nums[:-k]
causes the object pointed bynums
changed.
So, outside the methods, only the rotate2
really changes the object of ls2
.
CodePudding user response:
In your function rotate1
you are assigning a new variable nums
which replaces the variable nums
that came in the argument. This will not affect the list outside the function because you are replacing the variable that points to where the values are allocated in memory, you are not changing the values in memory. Essentially, your new list [3, 4, 1, 2]
is being stored in a new address in memory. Now you have your original list ls1
and the new list nums
allocated in different addresses in memory.
In your function rotate2
you are changing the values that are stored in memory, instead of changing the pointer. When you use nums[:]
the variable nums
remains untouched, what changes are the values in memory that the variable nums
points to. That's why your list outside gets updated too.