如何在异常处理中继续循环?

时间:2014-11-19 18:25:06

标签: python loops exception grid

我正在创建一个使用Moore的邻居操作的简单程序。因此,给定一个网格,一行和一列,它应该返回包含1的位置附近的单元格数量。它可以工作,除非在网格边缘给定一个位置。由于它正在检查它周围的所有网格,因此当它尝试检查网格外的位置时会抛出一个IndexError。我想要它做的只是忽略它而不停止,抛出错误,或操纵我的结果,然后转到下一个。但是我不确定如何,我尝试在IndexError上做一个例外但是一旦遇到它就退出循环。

def count_neighbours(grid, row, col):
    count = 0
    pos = grid[row][col]
    try:
        for cell in [grid[row+1][col],    #(0,-1) All relative to pos
                     grid[row-1][col],    #(0,1)
                     grid[row+1][col+1],  #(1,-1)
                     grid[row+1][col-1],  #(-1,-1)
                     grid[row][col-1],    #(-1,0)
                     grid[row][col+1],    #(1,0)
                     grid[row-1][col+1],  #(1,-1)
                     grid[row-1][col-1]]: #(-1,1)
            if cell == 1:
                count += 1
    except IndexError:
        pass
    return count

assert count_neighbours(((1, 1, 1),
                         (1, 1, 1),
                         (1, 1, 1),), 0, 2) == 3

3 个答案:

答案 0 :(得分:1)

循环正在停止,因为你正在尝试包装整个循环,除非你想要这样的东西

def count_neighbours(grid, row, col):                                                   count = 0                                                               
    pos = grid[row][col]                                                    
    for cell in [[row+1,col],    #(0,-1) All relative to pos           
                 [row-1,col],    #(0,1)                                
                 [row+1,col+1],  #(1,-1)                                
                 [row+1,col-1],  #(-1,-1)                               
                 [row,col-1],    #(-1,0)                                
                 [row,col+1],    #(1,0)                                 
                 [row-1,col+1],  #(1,-1)                                
                 [row-1,col-1]]: #(-1,1)                                
        try:                                                            
            temp_cell = grid[cell[0]][cell[1]]                                
            if temp_cell == 1:                                                   
                count += 1                                                  
        except IndexError:                                                      
            pass                                                                
    return count                                                            

assert count_neighbours(((1, 1, 1),                                         
                         (1, 1, 1),                                         
                         (1, 1, 1),), 0, 2) == 3

答案 1 :(得分:0)

尝试不同的方法,首先计算给定点的有效坐标,然后检查它们。

例如,您可以使用此功能:

def compute_coords_around(x, y, boundary):
    xcoords = [x-1, x, x+1]
    ycoords = [y-1, y, y+1]
    valid_coords = []

    for xc in xcoords:
        for yc in ycoords:
            if xc <= boundary and yc <= boundary:
                valid_coords.append((xc,yc))

    return valid_coords

并且假设您想要在3x3的矩阵中检查(2,2)的相邻单元格。您知道列或行的最大值是2.所以您可以:

compute_coords_around(2, 2, 2)

这会给你列表:

[(1, 1), (1, 2), (2, 1), (2, 2)]   

,同时:

compute_coords_around(1, 1, 2)

给你:

[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]

然后您的代码可以修改为:

def count_neighbours(grid, row, col):
    count = 0
    pos = grid[row][col]
    for (x, y) in compute_coords_around(row, col, len(grid) - 1)
        if grid[x][y] == 1:
            count += 1
    return count

答案 2 :(得分:0)

您需要更细粒度的异常处理(并且您的算法需要显式检查其他合法的 - 在Python中 - 索引小于零)。这是实现两者的一种方法:

OFFSETS = ((-1, -1), (-1, 0), (-1, 1),
           ( 0, -1),          ( 0, 1),
           ( 1, -1), ( 1, 0), ( 1, 1))

def count_neighbours(grid, row, col):
    count = 0
    for dr, dc in OFFSETS:
        try:
            x, y = row+dr, col+dc
            if x < 0 or y < 0:  # Disallow negative indices.
                raise IndexError
            if grid[x][y] == 1:  # Could also cause an IndexError.
                count += 1
        except IndexError:
            pass
    return count

assert count_neighbours(((1, 1, 1),
                         (1, 1, 1),
                         (1, 1, 1),), 0, 2) == 3

然而,必须在最内层循环中添加对负索引的显式检查有点难看。正如我在评论中提到的,在网格中添加额外的行和列肯定会简化处理,如下所示:

OFFSETS = ((-1, -1), (-1, 0), (-1, 1),
           ( 0, -1),          ( 0, 1),
           ( 1, -1), ( 1, 0), ( 1, 1))

def count_neighbours(grid, row, col):
    count = 0
    for dr, dc in OFFSETS:
        try:
            if grid[row+dr][col+dc] == 1:
                count += 1
        except IndexError:
            pass
    return count

# Note the changed position coordinate arguments.
assert count_neighbours(((0, 0, 0, 0),
                         (0, 1, 1, 1),
                         (0, 1, 1, 1),
                         (0, 1, 1, 1),), 1, 3) == 3