【问题标题】:How to raise an IndexError when slice indices are out of range?当切片索引超出范围时如何引发 IndexError?
【发布时间】:2015-10-30 17:37:43
【问题描述】:

Python Documentation 声明

切片索引被静默截断以落入允许范围

因此,在对列表进行切片时,无论使用什么 startstop 参数,都不会升高 IndexErrors

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

由于列表egg 不包含任何大于2 的索引,因此egg[5]egg[10] 调用将引发IndexError

>> egg[5]
Traceback (most recent call last):
IndexError: list index out of range

现在的问题是,当两个给定的切片索引都超出范围时,我们如何提出IndexError

【问题讨论】:

  • 为什么不呢?因为空切片结果仍然是有效对象。如果您想引发异常,请手动探测开始和结束索引,或针对您的边界显式测试 len(egg)
  • @MartijnPieters:感谢您的回复!我不确定这是否是重复的,因为我问的是“如何在切片序列时引发 IndexError”而不是“为什么切片索引超出范围工作” .但如果我错了,请纠正我:)
  • 您问了 两个 问题,使您的帖子过于宽泛。我欺骗了您回答第一个问题的上一个问题,并提供了您回答第二个问题的选项。
  • @MartijnPieters:好的,我明白了,我已经编辑了我的问题...
  • 那么什么时候应该引发异常呢?当两个索引都超出范围时?对于任何导致空切片的索引?负指数应该怎么办?对于起点 >= 终点且步幅不是负数的切片?请更具体地说明您希望引发错误的原因,因为您可能会将不同的情况视为错误。

标签: python exception indexing slice


【解决方案1】:

在 Python 2 中,您可以通过这种方式覆盖 __getslice__ 方法:

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)

然后使用你的类而不是list

>>> egg = [1, "foo", list()]
>>> egg = MyList(egg)
>>> egg[5:10]
Traceback (most recent call last):
IndexError: list index out of range

【讨论】:

    【解决方案2】:

    这里没有灵丹妙药;你必须测试两个边界:

    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()
    

    由于切片中的结束值是独占的,所以允许范围最大为length

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-06-28
      • 2019-11-25
      • 2020-12-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-21
      • 2013-07-28
      相关资源
      最近更新 更多