How to implement a slice in Python 3?

I read something about the slice in Python 3. Then I wrote a program and tried to implement it __getitem__(self, slice(s)). The code goes below:

class NewList:
    def __init__(self, lst):
        print('new list')
        self._list = lst
    def __getitem__(self, x):
        if type(x) is slice:
            return [ self._list[n] for n in range(x.start, x.stop, x.step) ]  #error?
        else:
            return self._list[x]
    ...

nl1 = NewList([1,2,3,4,5])
nl1[1:3]  #error occurs

Then I found out that it x.stepis equal None, which made the range raise exception. So how do I implement a method __getitem__?

+5
source share
4 answers

You need to use the method slice.indices. Given the length of your sequence, it returns a tuple of start, stop, step:

>>> s = slice(2, 5, None)
>>> s.indices(10)
(2, 5, 1)

>>> [x for x in range(*s.indices(10))]
[2, 3, 4]

>>> s.indices(3)
(2, 3, 1)

>>> s.indices(0)
(0, 0, 1)
+2
source

, , , . , getitem :

  def __getitem__( self, key ) :
    if isinstance( key, slice ) :
       m = max(key.start, key.stop)
       return [self[ii] for ii in xrange(*key.indices(m+1))]
    elif isinstance( key, int ) :
       #Handle int indices

, , None .

+4

If xthis is a slice, you can do the same as another condition:

return self._list[x]
+2
source

What about x.step or 1?

class NewList:
    def __init__(self, lst):
        print('new list')
        self._list = lst
    def __getitem__(self, x):
        if type(x) is slice:
            return [ self._list[n] for n in range(x.start, x.stop, x.step or 1) ]  #error?
        else:
            return self._list[x]

nl1 = NewList([1,2,3,4,5])
nl1[1:3]
0
source

All Articles