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?
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)
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With