当切片索引超出范围时如何引发 IndexError?
Posted
技术标签:
【中文标题】当切片索引超出范围时如何引发 IndexError?【英文标题】:How to raise an IndexError when slice indices are out of range? 【发布时间】:2015-10-30 17:37:43 【问题描述】:Python Documentation 声明
切片索引被静默截断以落入允许范围
因此,在对列表进行切片时,无论使用什么 start
或 stop
参数,都不会升高 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?的主要内容,如果未能解决你的问题,请参考以下文章
IndexError:使用beautifulsoup 抓取广告时列出的索引超出范围
如何在python中修复“IndexError:元组索引超出范围”?