【问题标题】:Python: List index out of range, don't know whyPython:列表索引超出范围,不知道为什么
【发布时间】:2014-06-19 17:43:50
【问题描述】:

我正在尝试遍历矩阵并检查与当前单元格接触且值为 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:

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

【问题讨论】:

  • if cells[i[0]][i[1]] == 1: 不在您的代码中。假设您的意思是if matrix[i[0]][i[1]] == 1:,您能否更具体地了解matrix 在此行之前的值是什么?
  • 当我复制粘贴到 stackoverflow 时,我将单元格重命名为矩阵,以便更清楚地了解它是什么,我只是忘记在帖子底部重命名它。我已经编辑了我的帖子,现在应该更有意义了。在此之前,矩阵用 0 或 1 填充,随机分布。
  • 如果您提供完整的堆栈跟踪,而不仅仅是异常,会更有帮助。
  • if x!=ROWS & y!=0: neighbors.append([x+1,y-1]) 如果这里的 x 是 ROWS-1(定义范围的最后一个)。在 x 上加一会在以后产生索引错误。假设 ROWS\COLS 是实际行数\cols。
  • OP:我在回答中提到了这一点,但通常矩阵是从左到右、从上到下的。尽管您在这里似乎没有遇到这个问题,但在大多数情况下,您想要执行 for x in range(COLS); for y in range(ROWS)matrix[y][x]

标签: python loops for-loop iteration indexoutofboundsexception


【解决方案1】:

问题是您使用的是&。这是按位与,而不是逻辑与。在 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,而不是它们是否等于ROWS-1COLS-1,它们是真正的边界条件。

【讨论】:

  • 好收获!你在我编辑我的时候发布了你的答案:)
  • 不幸的是,在将 & 替换为 'and' 后,我仍然遇到同样的错误
  • @Petefic M4rtini 在您的问题的 cmets 中发现了另一个错误
  • @AdamSmith 哦,是的,一个简单的错误。我也将其添加到我的答案中。
【解决方案2】:

编辑:我想我找到了

在进一步检查您的代码后,我发现您使用的是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

当然这不考虑对角线。不过,我很确定您可以弄清楚如何管理这些!

【讨论】:

    猜你喜欢
    • 2021-07-15
    • 1970-01-01
    • 1970-01-01
    • 2021-10-28
    • 1970-01-01
    • 2015-12-26
    • 1970-01-01
    • 2015-08-16
    • 2020-09-04
    相关资源
    最近更新 更多