Doubt about the slice function

1

At reply this question that Guilherme Nascimento P. did, there was a question about using the slice , so far I was unaware of it, and found it at documentation I was confused.

Searching here in SOpt did not find anything about it, the terms used in the search were: # and [python] slice .

Our friend @jsbueno commented :

  

The Python slice "function" mentioned in the first paragraph is not used as indicated. It just builds a slice object that is used internally to fetch sequence sessions, as explained in the rest of the answer. It is usually only used if you are implementing a sequence class that works as a list.

My question is: How is the correct use of the function slice ?

input = [ 'laranja', 'limão', 'melancia', 'mamão' ]
print(input[slice(1,-1)])
  

Note: As for the question tags, if there is one missing, just let me know.

    
asked by anonymous 28.12.2017 / 01:09

2 answers

2

The built-in call slice of Python is not properly a function - like some other Python calls, it is actually a class that creates the object slice .

The chances of you needing to use slice directly are quite small, but there are some uses - usually more for you to check if an object is a slice and uses it, rather than to create one directly. p>

The slice object is what is used internally by Python when using slice notation to delimit a subset of a string, such as a list or a string.

This notation is nothing more than using numbers separated by : within a couple of brackets [ ] used as index - as we do in:

In [70]: a = "banana"

In [71]: a[1:4]
Out[71]: 'ana'

Or

In [72]: b = list(range(10, 20))

In [73]: b
Out[73]: [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

In [74]: b[:-5:2]
Out[74]: [10, 12, 14]

(In this case, the [:-5:2] slice should be read as: take the substring from the beginning, up to 5 positions before the end, counting from 2 to 2).

As you probably know, all operations on Python objects are translated internally for calls to "magic" methods that have a predefined name - the best documentation for these methods is the language data model at this address : link

In particular, when we are going to get, assign, or delete (with the del ) a sub-string within a string, Python calls respectively the methods __getitem__ , __setitem__ and __delitem__ of the object representing the sequence.

In this process, Python transforms numbers placed in slice notation into brackets into a slice object. That is, Python even calls the "function" slice for us.

The object slice is very simple, we can view the documentation or introspect it using dir :

In [75]: a = slice(1, 4)


In [76]: dir(a)
Out[76]: 
[...
 'indices',
 'start',
 'step',
 'stop']

(I deleted the magic methods of the slice because they are not important) - if you look at the "start", "step" and "stop", correspond to the attributes we passed to the beginning and end of the sequence, and "None "for step (step), which is the third optional argument)

The indices method requires an integer represented by the length of the sequence - and everything it does is, taking into account the length of the sequence passed as a parameter, calculates the start, end, and step indexes already taking into account the omitted parameters (that is, left blank before or after : ), negative indexes, and so on ... The values returned by the call to the indice method can be used directly in the% function range to generate all the indices of that slice.

It is easier to visualize with an example: let's create a subclass of list that always returns all elements of a slice transformed into strings:

class StringSliceList(list):
    def __getitem__(self, indices):
         if isinstance(indices, slice):
              results = []
              start, stop, step = indices.indices(len(self))
              for i in range(start, stop, step):
                   results.append(str(super().__getitem__(i)))
         else:   
            results = super().__getitem__(indices)
         return results

Ready, so we can play on the interactive terminal:

In [84]: a = StringSliceList(range(20))

In [85]: a[5:10]
Out[85]: ['5', '6', '7', '8', '9']

The slice object can be passed directly between brackets, but it will always be less readable than directly using notation with ":":

In [86]: a[slice(5,10)]
Out[86]: ['5', '6', '7', '8', '9']

I believe your maintenance as a built-in Python default is more of a slippage than anything else - it's a class that might as well be in the types module. But as this got in the transition to Python 3, it's also very unimportant thing to break the compatibility, so it's getting.

Trivia:

In the case of a multi-dimensional index, where multiple axes are separated by , within brackets, such as those used in NumPy arrays, each component separated by , can be converted to a slice object % separate.

class Test:
   def __getitem__(self, indices):
       print(indices)

Can be used:

In [89]: Test()[1:10, :, -1:5:10]
(slice(1, 10, None), slice(None, None, None), slice(-1, 5, 10))

And this does not happen if you put an extra pair of () inside [], why does this create a tuple that does not have the components converted to objects of type slice :

In [90]: Test()[(1:10, :, -1:5:10)]
  File "<ipython-input-90-32002bdbab86>", line 1
    Test()[(1:10, :, -1:5:10)]
             ^
SyntaxError: invalid syntax
    
28.12.2017 / 17:43
-1

Slice in a list would be the equivalent to use: ":"

input = ['laranja','limão','melancia','mamão']
print(input[1:-1])

There are countless ways for you to delimit a list. See this question in the English stack, they explain very well the use of the slice:

Understanding Python's slice notation

    
28.12.2017 / 12:32