What does colon at assignment for list[:] = […] do in Python
Question:
I came accross the following code:
# O(n) space
def rotate(self, nums, k):
deque = collections.deque(nums)
k %= len(nums)
for _ in xrange(k):
deque.appendleft(deque.pop())
nums[:] = list(deque) # <- Code in question
What does nums[:] =
do that nums =
does not? For that matter, what does nums[:]
do that nums
does not?
Answers:
nums = foo
rebinds the name nums
to refer to the same object that foo
refers to.
nums[:] = foo
invokes slice assignment on the object that nums
refers to, thus making the contents of the original object a copy of the contents of foo
.
Try this:
>>> a = [1,2]
>>> b = [3,4,5]
>>> c = a
>>> c = b
>>> print(a)
[1, 2]
>>> c = a
>>> c[:] = b
>>> print(a)
[3, 4, 5]
This syntax is a slice assignment. A slice of [:]
means the entire list. The difference between nums[:] =
and nums =
is that the latter doesn’t replace elements in the original list. This is observable when there are two references to the list
>>> original = [1, 2, 3]
>>> other = original
>>> original[:] = [0, 0] # changes the contents of the list that both
# original and other refer to
>>> other # see below, now you can see the change through other
[0, 0]
To see the difference just remove the [:]
from the assignment above.
>>> original = [1, 2, 3]
>>> other = original
>>> original = [0, 0] # original now refers to a different list than other
>>> other # other remains the same
[1, 2, 3]
Note: vincent thorpe’s comments below are either incorrect or irrelevant to the question. This is not a matter of value vs reference semantics, nor whether you apply the operator to an lvalue or rvalue.
I came accross the following code:
# O(n) space
def rotate(self, nums, k):
deque = collections.deque(nums)
k %= len(nums)
for _ in xrange(k):
deque.appendleft(deque.pop())
nums[:] = list(deque) # <- Code in question
What does nums[:] =
do that nums =
does not? For that matter, what does nums[:]
do that nums
does not?
nums = foo
rebinds the name nums
to refer to the same object that foo
refers to.
nums[:] = foo
invokes slice assignment on the object that nums
refers to, thus making the contents of the original object a copy of the contents of foo
.
Try this:
>>> a = [1,2]
>>> b = [3,4,5]
>>> c = a
>>> c = b
>>> print(a)
[1, 2]
>>> c = a
>>> c[:] = b
>>> print(a)
[3, 4, 5]
This syntax is a slice assignment. A slice of [:]
means the entire list. The difference between nums[:] =
and nums =
is that the latter doesn’t replace elements in the original list. This is observable when there are two references to the list
>>> original = [1, 2, 3]
>>> other = original
>>> original[:] = [0, 0] # changes the contents of the list that both
# original and other refer to
>>> other # see below, now you can see the change through other
[0, 0]
To see the difference just remove the [:]
from the assignment above.
>>> original = [1, 2, 3]
>>> other = original
>>> original = [0, 0] # original now refers to a different list than other
>>> other # other remains the same
[1, 2, 3]
Note: vincent thorpe’s comments below are either incorrect or irrelevant to the question. This is not a matter of value vs reference semantics, nor whether you apply the operator to an lvalue or rvalue.