当切片索引超出范围时如何引发 IndexError?

Posted

技术标签:

【中文标题】当切片索引超出范围时如何引发 IndexError?【英文标题】:How to raise an IndexError when slice indices are out of range? 【发布时间】: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:好的,我明白了,我已经编辑了我的问题... 那么什么时候应该引发异常呢?当两个索引都超出范围时?对于任何导致空切片的索引?负指数应该怎么办?对于起点 >= 终点且步幅不是负数的切片?请更具体地说明您希望引发错误的原因,因为您可能会将不同的情况视为错误。 【参考方案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

【讨论】:

以上是关于当切片索引超出范围时如何引发 IndexError?的主要内容,如果未能解决你的问题,请参考以下文章

csv,IndexError:列表索引超出范围

Python:IndexError:列表索引超出范围

IndexError:使用beautifulsoup 抓取广告时列出的索引超出范围

如何在python中修复“IndexError:元组索引超出范围”?

IndexError:在pyspark shell上使用reduceByKey操作时列出索引超出范围

Networkx:通过循环遍历节点列表添加属性时,IndexError:列表索引超出范围