How to raise an IndexError when slice indices are out of range?
Solution 1
In Python 2 you can override __getslice__
method by this way:
class MyList(list):
def __getslice__(self, i, j):
len_ = len(self)
if i > len_ or j > len_:
raise IndexError('list index out of range')
return super(MyList, self).__getslice__(i, j)
Then use your class instead of list
:
>>> egg = [1, "foo", list()]
>>> egg = MyList(egg)
>>> egg[5:10]
Traceback (most recent call last):
IndexError: list index out of range
Solution 2
There is no silver bullet here; you'll have to test both boundaries:
def slice_out_of_bounds(sequence, start=None, end=None, step=1):
length = len(sequence)
if start is None:
start = 0 if step > 1 else length
if start < 0:
start = length - start
if end is None:
end = length if step > 1 else 0
if end < 0:
end = length - end
if not (0 <= start < length and 0 <= end <= length):
raise IndexError()
Since the end value in slicing is exclusive, it is allowed to range up to length
.
![elegent](https://i.stack.imgur.com/MzJvW.jpg?s=256&g=1)
elegent
from stuffYouNeedToKnow import atLeastALittleBit you = YourRealYou() while you.doWhatYouLove == ":)": you.loveWhatYouDo()
Updated on June 15, 2022Comments
-
elegent about 2 years
The Python Documentation states that
slice indices are silently truncated to fall in the allowed range
and therefor no
IndexErrors
are risen when slicing a list, regardless whatstart
orstop
parameters are used:>>> egg = [1, "foo", list()] >>> egg[5:10] []
Since the list
egg
does not contain any indices greater then2
, aegg[5]
oregg[10]
call would raise anIndexError
:>> egg[5] Traceback (most recent call last): IndexError: list index out of range
The question is now, how can we raise an
IndexError
, when both given slice indices are out of range?-
Martijn Pieters almost 9 yearsWhy not? Because an empty slice result is still a valid object. If you want to raise exceptions, probe the start and end indices manually, or explicitly test for
len(egg)
against your boundaries. -
elegent almost 9 years@MartijnPieters: Thanks for your reply! I am not sure if this is a duplicate because I ask about "How to raise an IndexError when slice a sequence" and not the "Why slicing index out of range works". But correct me If I am wrong :)
-
Martijn Pieters almost 9 yearsYou asked two questions, making your post too broad. I duped you to a previous question that answers the first, and provided your options to answer the second.
-
elegent almost 9 years@MartijnPieters: Ok I see, I have a edited my question...
-
Martijn Pieters almost 9 yearsSo when should an exception be raised? When both indices are out of bounds? For any indices that result in an empty slice? What should happen with negative indices? For slices where the start point >= end point and the stride isn't negative? Please be more specific as to why you want the error to be raised, because there are different scenarios that you may see as an error.
-
elegent almost 9 yearsAs I said "I want to raise an exception when both of the given slice indices are out of range". In all other cases the result would be the same as a "normal" size and return an empty list if a slice is not possible.
-
Martijn Pieters almost 9 yearsThen just test for both indices against the length of the list and raise an exception manually when both are out of range. You'll have to handle the
None
and negative cases, but that's it. There is no magic bullet here. -
elegent almost 9 yearsThanks :) Ok that was exactly my question.
-