繁体   English   中英

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

[英]How can I continue a loop inside exception handling?

我正在创建一个使用Moore's Neighbourhood运行的简单程序。 因此,给定网格,行和列,它应该返回包含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

循环正在停止,因为您尝试将整个循环包装起来,除了您想要这样的东西

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

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

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

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

您需要更细粒度的异常处理(并且您的算法需要显式检查是否合法(在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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM