通过“通过”更正索引错误,但仍然出现“列表索引超出范围”错误吗?

时间:2019-11-04 23:08:22

标签: python arrays range

我对python还是很陌生,我正在从事一些复杂(但很有趣!)的项目。我不会赘述过多,但我已经注意到,以前类似的问题往往是针对非常具体的情况,这使它们对我来说很难提取任何东西,但肯定会让人们更容易尝试答案。

我实际上是使用36x36矩阵(在我的代码中简称为“数组”),其中左下角是条目0,其上方的条目是1,依此类推,直到到达第36个条目为止左上角,然后返回到条目0右侧的第37个条目,依此类推。对于给定的条目,我想知道参数右侧,左侧,上侧和下侧的条目的值。当然,有几种边缘情况不会有4个邻居,因此我已尽力将这些情况考虑在内,但似乎出现了不一致的错误。

这是我尝试过的最新内容:

def neighbors(i):
    neighbors_array = []
    if array[i+1] in array:
        neighbors_array.append(array[i+1])
    if array[i-1] in array:
        neighbors_array.append(array[i-1])
    if array[i+36] in array:
        neighbors_array.append(array[i+36])
    if array[i-36] not in array:
        neighbors_array.append(array[i-36])
    return neighbors_array

对于数组中间的一个参数(例如800),我得到的4个值与单独打印array[i+1]array[i-1]等时得到的值完全匹配。但是对于一个参数我知道在矩阵的最左列中,我得到一个包含4个条目的输出数组,尽管我只期望3个,因为该参数没有与之关联的[i-36]元素。对于我知道在最右边一栏中的参数,我得到IndexError: list index out of range

我对为什么两个极端情况没有相同的问题感到困惑,并且我想解决两个问题。至于顶部和底部行中的条目,我也得到了意外的4条目输出,除了右上角和右下角外,我得到了索引错误。

我曾尝试将数组转换为实际的矩阵,但是邻居函数的输出更为复杂,无论如何我都会遇到类似的问题,所以我认为我会坚持使用数组。

2 个答案:

答案 0 :(得分:1)

这不能用作边界检查:

if array[i-1] not in array:
    pass

因为一旦您说出array[i-1],您就将引发一个异常,而您的if谓词甚至还没有完成评估。在将i用作数组索引之前,您需要检查if i not in range(len(array)): 是有效的索引。

这是进行这种边界检查的惯用方式:

%

对于您要“包装”超出范围的值的特定用例,我建议您使用模(for neighbor in [i-1, i+1]: neighbors_array.append(array[neighbor % len(array)]) )运算符,而不是使用范围检查来单独包装一个方向或另一个方向。只要让数学为您完成工作即可。 :)

36 % 36 == 0

因为-1 % 36 == 35if __name__ == '__main__':

答案 1 :(得分:0)

您看到的实际问题在代码array[something] in array中(最初是array[i+36] not in array,依此类推)。

如果我们尝试逐步评估这一点,则会得到以下信息:

  1. 首先评估array[something]。这可能会导致IndexError。如果成功,我们会有一些value
  2. 现在对value in array进行评估,就像我们以前从True本身获得value一样,在我们的情况下,它将始终为array

解决方案:

对于列表,您应该检查列表的长度以防止IndexError

if len(array) > i+36:
    do_whatever_with(array[i+36])

Python方法:

在python中,“请求宽恕而不是许可”被认为是一种很好的样式,因此可以使用try-access-except-cleanup模式代替if-in-range-do模式:

try:
    do_whatever_with(array[i+36])
except IndexError:
    pass # because you just skipped the case in your original code as well