📜 ⬆️ ⬇️

Everything you wanted to know about slices

Little intro. I am sure that everyone who used the python for some time loved expressions in rectangular brackets. In this article, I want to tell from "a" to "z" about sections. First, a little about terminology: in English they are called “slice”. I will call them “slices”, then “slices”, as in my understanding of the word. We will all learn from examples. For me, such a method would be the most convenient, fast and simple.
For starters, the most common use. Create a copy of a sequence or part of it.
Consider a slice as part of the sequence. For example, several slices from the list:
>>> s = [1, 2, 3, 4, 6] #  >>> s[:] # ,    [1, 2, 3, 4, 6] >>> s[1:] #     [2, 3, 4, 6] >>> s[-3:] #  3  [3, 4, 6] >>> s[2:-2] #    2 [3] 

That's not all,
Not everyone knows, but there can be slices with three parameters:
 >>> s[::2] #  [1, 3, 6] >>> s[1:4:2] #       2 [2, 4] 

All these actions can be rotated with strings, tuples and lists.
 >>> "Hello Dolly!"[1::2] 'el ol!' 

Completely forgot, thanks xeningem :
 >>> "God saw I was dog"[::-1] 'god saw I was doG' >>> #    ,    .  . 

But that's not all, there are several actions with slices that can only be done with lists (well, almost). The point is that they are the only basic sequences that can change, and, for which, the order matters (it is impossible to make cuts from dictionaries and sets / sets). Next comes the conversation about slices that change the sequence.
Slices can be deleted, for example:
 >>> s = list(range(10)) # 0..9 >>> del s[3: -2: 2] #        2 >>> s [ 0, 1, 2, 4, 6, 8, 9] 

You can also insert elements:
In the replacement option:
 >>> s[2:5:2]=list("AF") #  [0, 1, 2, 4, 6, 8, 9],      ['A','F'] >>> #,       ,     >>> s [ 0, 1, 'A', 4, 'F', 8, 9] 

Well, or the insertion option is simpler:
 >>> s[3:4] = ["4 was here"] #    >>> s [ 0, 1, 'A', '4 was here', 'F', 8, 9] >>> s[1:1] = ["after zero"] #, ,  >>> s [ 0, 'after zero', 1, 'A', '4 was here', 'F', 8, 9] 

If we want to create a class from which to slice? There is simply no place, for this there are two ways:
Wrong:
1) Override the __getslice__, __delslice__ and __setslice__ functions. But this is an obsolete method (in 2.0 marked as deprecated)
And correct:
2) Override __getitem__, __setitem__ and __delitem__.
At first glance, everything seems to be extremely simple, but if you look closely, then __getitem __ (self, key) gets only one parameter, key, and we can have 3 integers from the slice ... Everything is very simple: in the case when someone tries cut a piece from our object, the key will receive a function of type slice:
 >>> class MySliceble(): def __getitem__(self, key): if isinstance(key, slice): return list(range(key.start, key.stop, key.step)) else: raise Exception("Trying to access by index") >>> my = MySliceble() >>> my[2:10:1] [2, 3, 4, 5, 6, 7, 8, 9] 

Of course, the example is very symbolic, but you can understand: an object of the slice class has three properties: start, stop, and step, corresponding to numbers from slice brackets. You need to be careful if the number is omitted, then the value will be None, for example [::] will be slice (None, None, None) and [: -3] will be slice (None, -3, None).
We do replacement / insertion and removal of slices by analogy.
As an exercise, you can try to reload the dictionary so that it can be sliced. In Python 3, this will start as a class SliceableDict (dict):
Well, everything seems to be about slices.
If I missed it, I will gladly learn it and add it.

Upd1: saved up 5 karmas, moved blog to pythonium. Thank.
Upd2: Thanks for the comments, corrected, added.

')

Source: https://habr.com/ru/post/89456/


All Articles