Как я могу продолжать цикл внутри обработки исключений?

голоса
0

Я создаю простую программу, которая работает с помощью Neighborhood Мура. Поэтому, учитывая сетку, строку и столбец, он должен вернуть количество клеток в непосредственной близости от позиции, которые содержат 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
Задан 19/11/2014 в 16:25
источник пользователем
На других языках...                            


3 ответов

голоса
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
Ответил 19/11/2014 в 16:38
источник пользователем

голоса
0

Попробуйте другой подход, сначала вычислить действительные COORDS для данной точки, а затем проверить на них.

Например, вы можете использовать эту функцию:

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

и позволяет сказать, что вы хотите проверить на соседних клетках (2, 2) в виде матрицы 3х3. Вы знаете, что максимальное значение столбца или строки равны 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
Ответил 19/11/2014 в 16:55
источник пользователем

голоса
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
Ответил 19/11/2014 в 17:18
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more