Reputation: 413
I wish to bring that last k elements of 'nums' array to the first. Like, Input:
nums = [1,2,3,4,5,6,7], k = 3
Output:
[5,6,7,1,2,3,4]
I have the following code:
class Solution(object):
def rotate(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: None Do not return anything, modify nums in-place instead.
"""
n = len(nums)
k = k % n
nums[:] = nums[n-k:] + nums[:n-k]
This works perfectly fine i.e. brings the last k elements to the beginning and nums shows [5,6,7,1,2,3,4]. But once I type the following nums = nums[n-k:] + nums[:n-k]
, it shows the resultant nums array as being the same original [1,2,3,4,5,6,7].
My question is, why is the change in output taking place? On googling and upon reding certain other threads in this forum pertaining to 'List Referencing and copying', I could realize that nums =
is something about list referencing but nums[:]
is like a mere copy of the list. But having said thiat, why is this change in output taking place? What's happening inside both the commands?
Seems like nums
and nums[:]
aren't yet clear to me. Please help.
Upvotes: 1
Views: 156
Reputation: 1115
In Python List Slicing,
To Get all the Items After a Specific Position use
nums[pos:]
#( pos for position ) and To Get all the Items Before a Specific Position usenums[:pos]
Slicing is a command describing how to display data from the original list and it's a Shallow copy operation. Shallow copies don’t actually copy each element’s value. Instead, they reference the memory location of each of the values from List nums
Here print(nums[:]) returns all elements of the list like print(nums)but when assigned to a slicing operation :
nums=nums[len(nums)-k%len(nums):]+nums[:len(nums)-k%len(nums)]
ornums= nums[n-k:] + nums[:n-k]
Here assigning that to {nums} has no effect on the previous value of the variable.
But
nums[:]=nums[len(nums)-k%len(nums):]+nums[:len(nums)-k%len(nums)]
ornums[:]= nums[n-k:] + nums[:n-k]
here assigning it to nums[:] inserts it into the existing list, replacing all of the previous elements.
Solution for Problem -> to bring that last k elements of 'nums' array to the first:
def rotate(self, nums: List[int], k: int):
nums[:]=nums[len(nums)-k%len(nums):]+nums[:len(nums)-k%len(nums)]
Upvotes: 1
Reputation: 4510
The assignment nums = nums[n-k:] + nums[:n-k]
would be equivalent to create a new list in memory (with the elements reversed), and changing the pointer nums
to point to that new list. But since the variable nums
that you change is local to the function, this change does not affect to the external one passed as parameter. Check follow diagram for better understanding:
The assignment nums[:] = nums[n-k:] + nums[:n-k]
would be equivalent to write a new reversed list at the same address pointed by nums
, because the slice allows to replace part of a list with new contents.
In this case you are not changing the variable nums
, but the data pointed by it.
Example Code:
def rotate(nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: None Do not return anything, modify nums in-place instead.
"""
n = len(nums)
k = k % n
# in function
# nums[:] = nums[n-k:] + nums[:n-k]
nums = nums[n-k:] + nums[:n-k]
# in scope
nums = [1,2,3,4,5,6,7]
k = 3
rotate(nums, k)
print(nums)
Upvotes: 5