如何';忽略';Python中的索引超出范围错误

如何';忽略';Python中的索引超出范围错误,python,conways-game-of-life,indexoutofrangeexception,Python,Conways Game Of Life,Indexoutofrangeexception,我的老师让我做一个Python版的“生命游戏”, 所以在我完成了大部分代码之后。我怀疑这是一个相当普遍的问题:角和边没有8个邻居。因此,使用以下代码会给我一个索引超出范围的异常: neighbors = (a[x-1][y-1]+a[x-1][y]+a[x-1][y+1]+a[x][y-1]+a[x][y+1] +a[x+1][y-1]+a[x+1][y]+a[x+1][y+1]) 因此,我不想使用大量的if语句,而是想捕获超出范围的索引并传递值0。 我将如何尝试做到

我的老师让我做一个Python版的“生命游戏”, 所以在我完成了大部分代码之后。我怀疑这是一个相当普遍的问题:角和边没有8个邻居。因此,使用以下代码会给我一个索引超出范围的异常:

neighbors = (a[x-1][y-1]+a[x-1][y]+a[x-1][y+1]+a[x][y-1]+a[x][y+1]
             +a[x+1][y-1]+a[x+1][y]+a[x+1][y+1])
因此,我不想使用大量的
if
语句,而是想捕获超出范围的索引并传递值0。
我将如何尝试做到这一点?

使您的实际电路板变宽变长2个单元格,用零填充边距,并使用从
1
长度(或宽度)-2
的索引。我将编写一个助手函数,您可以调用该函数返回值或零(伪代码):

def getValue(x,y)
如果x<0或y<0或x>xbound或y>ybound:
返回0
返回[x][y]

然后,您可以使用不同的参数多次调用
getValue
,我会用一个函数调用替换您的长表达式,如下所示:

def neighbors(a, x, y):
    total = 0
    for dx, dy in [(-1, -1), (-1, 0), (-1, 1),
                   ( 0, -1),          ( 0, 1),
                   ( 1, -1), ( 1, 0), ( 1, 1)]:
        try:
            total += a[x+dx][y+dy]
        except IndexError:
            pass
    return total

因为只有八个可能的邻居,为了达到最高速度,你可能需要考虑在上面的循环中解开以下内容:

def neighbors(a, x, y):
    xm1, xp1, ym1, yp1 = x-1, x+1, y-1, y+1
    total = 0
    try:
        total += a[xm1][ym1]
    except IndexError:
        pass
    try:
        total += a[xm1][y]
    except IndexError:
        pass
    try:
        total += a[xm1][yp1]
    except IndexError:
        pass
    try:
        total += a[x][ym1]
    except IndexError:
        pass
    try:
        total += a[x][yp1]
    except IndexError:
        pass
    try:
        total += a[xp1][ym1]
    except IndexError:
        pass
    try:
        total += a[xp1][y]
    except IndexError:
        pass
    try:
        total += a[xp1][yp1]
    except IndexError:
        pass
    return total

创建一个函数来检查每个位置的每个x,y将需要九个函数调用来计算相同的值(以及每次对一个非平凡条件表达式的求值)。

如果要在外部假设零,我会用边框或零填充原始数组。如果在函数中使用
try/except
,会更像python。我同意使用
try/except
,但我想不出一个比只使用
getValue(x,y)
函数更有效的方法。我的意思是在函数中使用
try/except
,而不是对索引进行边界测试。不管怎样,计算总数需要八到九个函数调用。是的,@martineau I肯定可以在这个函数中使用
try/catch
,而不是使用条件调用。好球!“开箱即用”的好例子thinking@Brent:事实上,这是一个相当有名的方法。也许只是字面上的开箱即用的填充:)非常小
;-):不管它是否为人所知,这是一种非常好的方法,尤其是在您已经编写了一系列包含硬编码索引值的代码之前就知道它是一种非常好的方法…@EugeneSh。我也有双关语。我知道这项技术不是他发明的,而是他把它正确地应用到了这个问题上。
def neighbors(a, x, y):
    xm1, xp1, ym1, yp1 = x-1, x+1, y-1, y+1
    total = 0
    try:
        total += a[xm1][ym1]
    except IndexError:
        pass
    try:
        total += a[xm1][y]
    except IndexError:
        pass
    try:
        total += a[xm1][yp1]
    except IndexError:
        pass
    try:
        total += a[x][ym1]
    except IndexError:
        pass
    try:
        total += a[x][yp1]
    except IndexError:
        pass
    try:
        total += a[xp1][ym1]
    except IndexError:
        pass
    try:
        total += a[xp1][y]
    except IndexError:
        pass
    try:
        total += a[xp1][yp1]
    except IndexError:
        pass
    return total