How to raise an IndexError when slice indices are

2019-04-30 02:56发布

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 what start or stop parameters are used:

>>> egg = [1, "foo", list()]
>>> egg[5:10]
[]

Since the list egg does not contain any indices greater then 2, a egg[5] or egg[10] call would raise an IndexError:

>> 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?

2条回答
兄弟一词,经得起流年.
2楼-- · 2019-04-30 03:28

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
查看更多
手持菜刀,她持情操
3楼-- · 2019-04-30 03:37

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.

查看更多
登录 后发表回答