Python:列表索引超出范围,不知道为什么
我正在尝试遍历一个矩阵,检查当前单元格周围有多少个相邻的单元格值为1。但是我遇到了一个越界的错误,我不太明白为什么会这样。
for x in range(0,ROWS):
for y in range(0,COLS):
#get neighbors
neighbors = []
if x!=0 & y!=COLS:
neighbors.append([x-1,y+1])
if y!=COLS:
neighbors.append([x,y+1])
if x!=ROWS & y!=COLS:
neighbors.append([x+1,y+1])
if x!=0:
neighbors.append([x-1,y])
if x!=ROWS:
neighbors.append([x+1,y])
if x!=0 & y!=0:
neighbors.append([x-1,y-1])
if y!=0:
neighbors.append([x,y-1])
if x!=ROWS & y!=0:
neighbors.append([x+1,y-1])
#determine # of living neighbors
alive = []
for i in neighbors:
if matrix[i[0]][i[1]] == 1:
alive.append(i)
我收到的错误信息是:
IndexError: list index out of range
这个错误出现在这一行 if matrix[i[0]][i[1]] == 1:
为什么会出现越界的情况,我该怎么解决呢?
2 个回答
3
编辑:我想我找到了问题
经过仔细检查你的代码,我发现你用的是 if x!=0 & y!=0
。这里的 &
是按位与运算,而不是逻辑与运算,所以它不会给你想要的结果。你应该用 and
来代替 &
,看看这样做是否能解决你的问题。
我建议稍微调整一下代码,这样会更容易阅读。
for loc_x in range(ROWS):
for loc_y in range(COLS): # btw shouldn't ROWS/COLS be flipped?
# if your matrix isn't square this could be why
x_values = [loc_x]
if loc_x < ROWS: x_values.append(loc_x+1)
if loc_x > 0: x_values.append(loc_x-1)
y_values = [loc_y]
if loc_y < COLS: y_values.append(loc_y+1)
if loc_y > 0: y_values.append(loc_y-1)
neighbors = [(x,y) for x in x_values for y in y_values if (x,y) != (loc_x,loc_y)]
alive = [matrix[n[0]][n[1]] for n in neighbors if matrix[n[0]][n[1]]==1]
试着用你的代码运行这个,看看是否能解决问题。如果还是不行,你可能需要进一步测试。例如,可以把 alive
的定义放在 try/except
标签里,这样可以提供更好的错误追踪信息。
try:
alive = ...
except IndexError:
print("Location: {},{}\nneighbors: {}\nROWS:{}\nCOLS:{}".format(x_loc,y_loc, neighbors,ROWS,COLS))
raise
顺便提一下,我之前解决这个问题的方法是创建一些对象来保存相关信息,然后从上到下、从左到右检查每个字段的右边和下面的字段。例如:
class Field(object):
def __init__(self,x,y,value):
self.x = x
self.y = y
self.value = value
self.neighbors = neighbors
class Matrix(list):
def __init__(self,size):
self.ROWS,self.COLS = map(int,size.lower().split("x"))
for y in range(ROWS):
self.append([Field(x,y,random.randint(0,1)) for x in range(COLS)])
self.plot()
def plot(self):
for row in self:
for col in row:
try:
self[row][col].neighbors.append(self[row+1][col])
self[row+1][col].neighbors.append(self[row][col])
except IndexError: pass
try:
self[row][col].neighbors.append(self[row][col+1])
self[row][col+1].neighbors.append(self[row][col])
except IndexError: pass
当然,这样做并不能处理对角线的情况。不过我相信你能想出办法来处理这些问题!!
3
问题在于你使用了 &
。这个符号是按位与运算,而不是逻辑与运算。在Python中,你应该用 and
。比如:
if x!=0 and y!=COLS:
neighbors.append([x-1,y+1])
不过,使用按位与运算造成问题的真正原因是运算顺序——它的优先级更高!
>>> 1 != 2 & 3 != 3
True
>>> (1 != 2) & (3 != 3)
False
>>> 1 != (2 & 3) != 3
True
所以即使你的逻辑看起来没问题,但运算顺序意味着你代码的实际行为和你预期的差别很大。
你代码的另一个问题是,你在检查 x
和 y
是否等于 ROWS
和 COLS
,而不是检查它们是否等于 ROWS-1
和 COLS-1
,后者才是真正的边界条件。