我对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条目输出,除了右上角和右下角外,我得到了索引错误。
我曾尝试将数组转换为实际的矩阵,但是邻居函数的输出更为复杂,无论如何我都会遇到类似的问题,所以我认为我会坚持使用数组。
答案 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 == 35
,if __name__ == '__main__':
等
答案 1 :(得分:0)
您看到的实际问题在代码array[something] in array
中(最初是array[i+36] not in array
,依此类推)。
如果我们尝试逐步评估这一点,则会得到以下信息:
array[something]
。这可能会导致IndexError
。如果成功,我们会有一些value
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