>>> a = [3, 2]
>>> a[0:1][0] = 1
>>> a
[3, 2]
>>> a[0:1] = [1]
>>> a
[1, 2]
What does a[0:1]
mean?
a
, then a[0:1][0] = 1
should change the value of a
.a
, then a[0:1] = [1]
shouldn't change the value of a
.I think the result of the two is inconsistent with each other. Could you please help me work out the problem?
The short answer. Slicing lists does not generate copies of the objects in the list; it just copies the references to them. That is the answer to the question as asked.
The slice() method is a copying method. It does not alter this but instead returns a shallow copy that contains some of the same elements as the ones from the original array.
Python slice() Function The slice() function returns a slice object. A slice object is used to specify how to slice a sequence. You can specify where to start the slicing, and where to end. You can also specify the step, which allows you to e.g. slice only every other item.
In short, slicing is a flexible tool to build new lists out of an existing list. Python supports slice notation for any sequential data type like lists, strings, tuples, bytes, bytearrays, and ranges. Also, any new data structure can add its support as well.
Internally, this is a big difference:
>>> a = [3, 2]
>>> a[0:1][0] = 1
is a shorthand for
temp = a[0:1]
temp[0] = 1
and is internally expressed as
a.__getitem__(slice(0, 1)).__setitem__(0, 1)
resp.
temp = a.__getitem__(slice(0, 1))
temp.__setitem__(0, 1)
so it accesses a part of the list, making a separate object, and doing an assignment on this object, which is then dropped.
On the other hand,
>>> a[0:1] = [1]
does
a.__setitem__(slice(0, 1), [1])
which just operates on the original object.
So, while looking similar, these expressions are distinct on what they mean.
Let's test that:
class Itemtest(object):
def __init__(self, name):
self.name = name
def __repr__(self):
return self.name
def __setitem__(self, item, value):
print "__setitem__", self, item, value
def __getitem__(self, item):
print "__getitem__", self, item
return Itemtest("inner")
a = Itemtest("outer")
a[0:1] = [4]
temp = a[0:1]
temp[0] = 4
a[0:1][0] = 4
outputs
__setitem__ outer slice(0, 1, None) [4]
__getitem__ outer slice(0, 1, None)
__setitem__ inner 0 4
__getitem__ outer slice(0, 1, None)
__setitem__ inner 0 4
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