Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement slice in Python 3?

Tags:

python

slice

I read something about slice in Python 3. Then I wrote a program, tried to implement __getitem__(self, slice(s)). 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 x.step is None, which made range raise an exception. So, how should I implement the __getitem__ method?

like image 541
Alcott Avatar asked Aug 17 '11 03:08

Alcott


2 Answers

You need to use the slice.indices method. 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)
like image 110
Eryk Sun Avatar answered Oct 04 '22 20:10

Eryk Sun


In the case where you don't know the length of your object there is an obvious trick to circumvent this mandatory parameter. For example an infinite sequence's getitem can look like this:

  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

It will only fail if you don't give start and stop but with checking for None this could be handled too.

like image 37
rwst Avatar answered Oct 04 '22 21:10

rwst