I was asked this for a coding test and didn't know the answer. Anyone have any ideas?
-
possible duplicate of [What is the difference between list and list\[:\] in python?](http://stackoverflow.com/questions/4081561/what-is-the-difference-between-list-and-list-in-python) – Ignacio Vazquez-Abrams Aug 11 '11 at 22:08
-
1@Ignacio: No, this is not a duplicate -- that question makes no mention of the `a[:] = b` construct. – Adam Rosenfield Aug 11 '11 at 22:09
-
@Adam: Not even the part that starts "When assigning..."? – Ignacio Vazquez-Abrams Aug 11 '11 at 22:10
3 Answers
[:]
is the slice operator.
When it's on the left side, it overwrites the contents of the list without creating a new reference.
When it's on the right side, it creates a copy of the list with the same contents.

- 83,943
- 34
- 151
- 241
-
Ohhh ok it makes sense now. To clarify, id(a) doesn't change when doing a[:] = b. id(a) changes when doing a = b[:]. Is there a reason why one may be better than the other? – user701632 Aug 11 '11 at 22:26
-
Yes, you've got it exactly. If `c` also refers to the same list as `a`, then you might want to change the contents, so that both variables refer to the updated list. – recursive Aug 11 '11 at 22:28
a = b[:]
calls either __getslice__
or __getitem__
on b
and assigns the result to a
. In nearly all cases (e.g. lists, tuples, and other sequence types), this makes a shallow copy of the sequence; I don't know of any classes that don't implement that behavior, but you could have a user-defined type that did something different. Any other objects that previously referred to the old value of a
will continue to refer to that old value.
a[:] = b
, on the other hand, calls __setslice__
or __setitem__
to replace a subset of the elements of a
with those of the sequence b
. In this case, if the sequence type of a
is well-behaved, this will replace the entirety of a
, since the range :
without endpoints indicates the entire sequence. The difference here is that immutable types, such as tuples, will not allow you to perform __setslice__
(e.g. by throwing a TypeError
exception). Any other objects that previously referred to a
will also be updated, since the underlying object is being modified.
For mutable types such as list
, the result of a = b[:]
will be identical to a[:] = b
, in that a
will be a shallow copy of b
; for immutable types such as tuple
, a[:] = b
is invalid. For badly-behaved user-defined types, all bets are off. There's also a difference in what happens to other objects that referred to the same object as a
-- with a = b[:]
, they refer to the original value (a
), but with a[:] = b
, they refer to the modified object (shallow copy of b
).

- 390,455
- 97
- 512
- 589
In both cases you end up the list a
being a copy of the list b
. But the method used to accomplish this has changed.
a[:] = b
modifies the list a
so that it has the same elements as b
a = b[:]
produces a new list which is a copy of b
and replaces the list a
The difference is whether we've modified an existing list or created a new one.
To see the difference:
a = range(3)
b = range(4)
c = a # c and a now share the same list
a[:] = b
print "a", a
print "b", b
print "C", c
All three lists will print out the same. C and a share the same object, so when a
was modified so was c
a = range(3)
b = range(4)
c = a # c and a now share the same list
a = b[:]
print "a", a
print "b", b
print "C", c
Now c will not print out the same as a. After the assignment, a
and c
did not share the same object.
Speedwise, a[:] = b
is probably a little faster than a = b[:]
. The first form doesn't have to create a new list object, it can merely modify the existing list. A big part of this is that it can reuse the memory already owned by the list rather then allocating new memory.

- 75,655
- 22
- 151
- 221

- 44,070
- 10
- 68
- 83