Python:列表索引超出范围,不知道为什么

时间:2014-05-02 23:12:54

标签: python loops for-loop iteration indexoutofboundsexception

我试图遍历一个矩阵并检查触及当前单元格的值为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:列表索引超出范围

此行if matrix[i[0]][i[1]] == 1:

为什么这超出了范围,我应该如何解决?

2 个答案:

答案 0 :(得分: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

顺便说一下,我之前已经通过创建保存链接信息并从上到下从上到下并且每个都检查其右侧和下方的字段的对象来解决此问题。 E.g:

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

当然,这并没有照顾对角线。我很确定你可以弄清楚如何管理这些,但是!!

答案 1 :(得分:3)

问题是您使用的是&。这是一个有点明智的AND,而不是逻辑AND。在Python中,您只需使用and。例如:

if x!=0 and y!=COLS:
    neighbors.append([x-1,y+1])

然而,使用逐位AND导致问题的真正原因是操作顺序 - 它具有更高的优先级!

>>> 1 != 2 & 3 != 3
True
>>> (1 != 2) & (3 != 3)
False
>>> 1 != (2 & 3) != 3
True

因此,即使您的逻辑看起来正确,操作顺序也意味着您的代码的实际行为与您期望的完全不同。

您的代码的另一个问题是,您正在检查xy是否等于ROWSCOLS,而不是等于{{ 1}}和ROWS-1,这是真正的边界条件。