Slice in python, is a copy or just a pointer

>>>a = [3, 2] >>>a[0:1][0] = 1 >>>a [3, 2] >>>a[0:1] = [1] >>>a [1, 2] 

What does a[0:1] mean?

  • if it is a pointer to the range a, therefore a[0:1][0] = 1 should change the value of a.
  • if it is a copy of the range a, therefore a[0:1] = [1] should not change the value of a.

I think the result of the two is incompatible with each other. Could you help me solve the problem?

+6
source share
3 answers

Inside, this is a big difference:

 >>>a = [3, 2] >>>a[0:1][0] = 1 

is short for

 temp = a[0:1] temp[0] = 1 

and internally expressed as

 a.__getitem__(slice(0, 1)).__setitem__(0, 1) 

respectively.

 temp = a.__getitem__(slice(0, 1)) temp.__setitem__(0, 1) 

therefore, it accesses part of the list, creates a separate object, and assigns that object, which is then discarded.

Oto

 >>>a[0:1] = [1] 

does

 a.__setitem__(slice(0, 1), [1]) 

which only works with the source object.

Thus, with the same view, these expressions differ from what they mean.

Let me verify 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 

exits

 __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 
+6
source

Cutting the list creates a shallow copy - this is not a link to the original. Therefore, when you receive this fragment, it is not tied to the original list a . Therefore, you can try and change one element from it, but it is not stored in a variable so that no changes are made to any original list .

To clarify, from the first, when you do __getitem__ - access to part of the list (copy):

 a[0:1][0] = 1 

You are editing the fragment [0:1] , which is the only small copy of a , therefore you will not edit a .

But with the latter, __setitem__ is called, which, of course, will edit the object in place:

 a[0:1] = [1] 

You are directly referencing and editing part a , so it changes in real time.

+6
source
 The following statement: >>> a[0:1] = [1] 

assigns list [1] as a subset of list a from 0 to 1 .

By doing a[0:1][0] , you get the first element [3] , which is 3. Then, if you try to assign it a value of 1, it just won’t work, because 3 cannot be 1. However, if you stick to a[0:1] , you get [3] , which can be changed to [1] . Hope that helps

Examples

 >>> a = [1,2,3,4] >>> a[1:4] [2,3,4] >>> a[1:4] = [6,5,4,3,2] >>> a [1,6,5,4,3,2] 
0
source

All Articles