Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When does slicing operator create a shallow copy in Python?

Tags:

python

I would like to ask you for help about the behaviour of a slicing operator in Python.

  1. On the one hand we know that L[:] creates a shallow copy of the list L. To verify it one can just print id(L), id(L[:]) and notice that they are different.
  2. On the other hand we know that del L[:] removes references from the original object. It makes the original list empty - not the shallow copy of it. Of course I agree that creating a shallow copy, then removing references from it, would make little sense so I understand that here we want to operate on the original list.

Is there any rule saying when slicing operator creates a shallow copy and when it doesn't? How can I know it without manually testing it?

I searched for this and found these topics:

  • How does del operator work in list in python?
  • Explain Python's slice notation

but unfortunately they do not answer my question, at least I do not see it.

like image 943
Drizzt Avatar asked Feb 16 '16 18:02

Drizzt


People also ask

Does slice create a shallow copy?

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.

Does Python slicing create a copy?

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.

Is slicing operator shallow or deep copy?

The official Python docs say that using the slicing operator and assigning in Python makes a shallow copy of the sliced list.

Why does Python shallow copy?

A shallow copy creates a new object which stores the reference of the original elements. So, a shallow copy doesn't create a copy of nested objects, instead it just copies the reference of nested objects. This means, a copy process does not recurse or create copies of nested objects itself.


1 Answers

del L[:] is a distinct operation from accessing L[:], which is again a distinct operation from L[:] = x.

  • del L[:] calls __delitem__ on the object with a slice object.
  • L[:] calls __getitem__ with that slice object.
  • L[:] = x calls __setitem__ with the slice object and x.

These three operations can be implemented in very different ways, depending on what the object is. For built-in list types, __delitem__ erases the items specified in the slice, __setitem__ replaces the items with the items given, and __getitem__ returns a new (copied) list consisting of the elements specified.

However, not all objects have to behave this way. For example, with a NumPy array, __getitem__ with a slice returns a view of the array rather than a copy - modifying the view alters the original array.

like image 134
nneonneo Avatar answered Sep 19 '22 23:09

nneonneo