What, if any, is the difference between list
and list[:]
in python?
7 Answers
When reading, list
is a reference to the original list, and list[:]
shallow-copies the list.
When assigning, list
(re)binds the name and list[:]
slice-assigns, replacing what was previously in the list.
Also, don't use list
as a name since it shadows the built-in.

- 776,304
- 153
- 1,341
- 1,358
-
Which is faster when assigning? list or list[:] – Owais Akbani Jun 14 '21 at 18:30
The latter is a reference to a copy of the list and not a reference to the list. So it's very useful.
>>> li = [1,2,3]
>>> li2 = li
>>> li3 = li[:]
>>> li2[0] = 0
>>> li
[0, 2, 3]
>>> li3
[1, 2, 3]

- 5,293
- 14
- 70
- 122
li[:] creates a copy of the original list. But it does not refer to the same list object. Hence you don't risk changing the original list by changing the copy created by li[:].
for example:
>>> list1 = [1,2,3]
>>> list2 = list1
>>> list3 = list1[:]
>>> list1[0] = 4
>>> list2
[4, 2, 3]
>>> list3
[1, 2, 3]
Here list2
is changed by changing list1
but list3
doesn't change.

- 1,945
- 21
- 32
Another useful example is when assigning a different type to a list and list[:]. for example,
l = [1,2,3]
a = numpy.array([4,5,6])
l = a
print(l)
The result is a numpy array:
array([4, 5, 6])
while,
l = [1,2,3]
a = numpy.array([4,5,6])
l[:] = a
print(l)
the result is a list:
[4, 5, 6]

- 81
- 1
- 3
To apply the first list
to a variable will create a reference to the original list.
The second list[i]
will create a shallow copy.
for example:
foo = [1,2,3]
bar = foo
foo[0] = 4
bar and foo will now be:
[4,2,3]
but:
foo = [1,2,3]
bar = foo[:]
foo[0] = 4
result will be:
bar == [1,2,3]
foo == [4,2,3]
:
is to slice.

- 7,157
- 4
- 39
- 65
However, if the list elements are lists themselves, even list1 = list[:]
has its problems. Consider:
>>> a = [[1,2,3],[4,5,6],[7,8,9]]
>>> b = a[:]
>>> b[0].remove(2)
>>> b
[[1, 3], [4, 5, 6], [7, 8, 9]]
>>> a
[[1, 3], [4, 5, 6], [7, 8, 9]]
This happens because each list element being copied to b is a list itself, and this copying of lists involves the same problem that occurs with the normal list1 = list2
.
The shortest way out that I've found is to explicitly copy every list element this way:
>>> a = [[1,2,3],[4,5,6],[7,8,9]]
>>> b=[[j for j in i] for i in a]
>>> b
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> b[0].remove(2)
>>> b
[[1, 3], [4, 5, 6], [7, 8, 9]]
>>> a
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
Of course, for every additional degree of nesting in the nested list, the copying code deepens by an additional inline for
loop.

- 5,702
- 6
- 35
- 42
-
1This will run into serious problems if you have different or unknown levels of nesting in your outer list (`i` may not be iterable) If you have nested lists, you should be using the [copy](http://docs.python.org/library/copy.html) module, use `b = copy.deepcopy(a)` instead of nested for loops. – RoundTower Jul 12 '11 at 11:53
The first one references to the original list. The second one points to the copy of the original list.
Check this out!
>>> a = [1, 2, 3]
>>> b = a
>>> c = a[:]
>>> a == b
True
>>> a is b
True
>>> a == c
True
>>> a is c
False
>>> a.__repr__
<method-wrapper '__repr__' of list object at 0x7f87a9ba3688>
>>> a.__repr__()
'[1, 2, 3]'
>>> b.__repr__
<method-wrapper '__repr__' of list object at 0x7f87a9ba3688>
>>> c.__repr__
<method-wrapper '__repr__' of list object at 0x7f87ad352988>
Notice that both a and b point to the address 0x7f87a9ba3688 whereas, c points to 0x7f87ad352988.
The difference is crystal clear.
Both a and b reference to the original list object.
Whereas, c points to the copy (of the original list) and thus, it is in a different location.

- 393
- 4
- 13