I was asked this for a coding test and didn't know the answer. Anyone have any ideas?
[:]
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.
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
).
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 then
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With