list [var-1] получает последний вместо броска IndexError? - PullRequest
1 голос
/ 15 февраля 2020

Я знаю, что на этот вопрос довольно просто ответить, но я застрял на нем некоторое время. Я создаю алгоритм решения лабиринта в Python. Лабиринт сформирован так (0 = стена, 1 = пространство). Я сохраняю каждую строку в виде вложенного списка:

data = [
         [0,0,0,0,0,0,0,1,0,0,0],
         [0,1,1,1,0,1,0,1,1,1,0],
         [0,1,0,1,0,1,0,1,0,1,0],
         [0,1,0,1,1,1,0,1,0,1,0],
         [0,1,0,0,0,1,0,1,0,0,0],
         [0,1,1,1,0,1,0,1,1,1,0],
         [0,1,0,1,0,1,0,0,0,1,0],
         [0,1,0,1,0,1,1,1,0,1,0],
         [0,1,0,1,0,0,0,1,0,1,0],
         [0,1,0,1,1,1,0,1,1,1,0],
         [0,0,0,0,0,1,0,0,0,0,0]
        ]

Для удобства просмотра моя программа переводит эти данные в следующее:

◼︎ ◼︎ ◼︎ ◼︎ ◼︎ ◼︎ ◼︎   ◼︎ ◼︎ ◼︎
◼︎       ◼︎   ◼︎       ◼︎
◼︎   ◼︎   ◼︎   ◼︎   ◼︎   ◼︎
◼︎   ◼︎       ◼︎   ◼︎   ◼︎
◼︎   ◼︎ ◼︎ ◼︎   ◼︎   ◼︎ ◼︎ ◼︎
◼︎       ◼︎   ◼︎       ◼︎
◼︎   ◼︎   ◼︎   ◼︎ ◼︎ ◼︎   ◼︎
◼︎   ◼︎   ◼︎       ◼︎   ◼︎
◼︎   ◼︎   ◼︎ ◼︎ ◼︎   ◼︎   ◼︎
◼︎   ◼︎       ◼︎       ◼︎
◼︎ ◼︎ ◼︎ ◼︎ ◼︎   ◼︎ ◼︎ ◼︎ ◼︎ ◼︎

Поиск пробела surrounding_spaces имеет решающее значение для успеха моей программы, поскольку я использую это, чтобы найти тупики. Тем не менее, отверстия в лабиринте могут рассматриваться программой как тупик, потому что есть только один способ добраться до отверстия. Чтобы бороться с этим, я полагаюсь на программу, которая выбрасывает IndexError в get_surrounding(), так что один из элементов в surrounding_spaces открытия * равен None.

В main() я перебираю каждый пространство, равное 1, которое является допустимым пространством, которое может занять программа.

def main():
    row_ind = 0
    for row in data:
        space_ind = 0
        for space in row:
            if space == 1:
                get_surrounding(row_ind, space_ind)
            space_ind += 1
        row_ind += 1

В get_surrounding() я создаю list с surrounding_spaces текущего row. Вот где я полагаюсь на IndexError, так что программа осознает, что это открытие, а не тупик:

def get_surrounding(row, space):
    try:
        left = data[row][space - 1]
    except:
        left = None
    try:
        right = data[row][space + 1]
    except:
        right = None
    try:
        up = data[row - 1][space]
    except:
        up = None
    try:
        down = data[row + 1][space]
    except:
        down = None

    surrounding_spaces = [left, right, up, down]
    print("[" + str(row) + ", " + str(space) + "]:" + str(surrounding_spaces))

Вывод этого совершенно правильно. surrounding_spaces открытия в последнем row из data: [0, 0, 1, None]

Однако верхняя строка является исключением (data[0]). У есть отверстие в data[0][7]. Когда переменная up установлена ​​в get_surrounding(), она обрабатывает первую строку как последнюю строку , потому что data[row-1][space], что по сути data[-1][space] как row = 0. Использование -1 в качестве индекса дает элемент last для list, и я не хочу рассматривать его как последний row. В моем случае, когда top row повторяется, я хочу, чтобы data[row-1][space] выбросил IndexError, потому что row в data до row0[0] нет. Если есть более простой способ выполнить sh, любые предложения приветствуются.

Желаемый вывод

[0, 7]:[0, 0, None, 1]
[10, 5]:[0, 0, 1, None]

Фактический вывод

# lists are formed like so: [left, right, up, down]
# the up value in the first list should be None, but it is 0 because when the up value is set the program treated  
[0, 7]:[0, 0, 0, 1]
[10, 5]:[0, 0, 1, None]

Примечание

Чтобы перевести данные для более удобного просмотра, я использовал пользовательский класс:

class MazeData:
    def __init__(self, data):
        self.data = data

    def display(self):
        data = self.data
        length = len(data[0])
        prettified_data = []
        space_ids = {0:"◼︎", 1:" ", 2:"@", 3:"•"}
        for row in data:
            line = []
            for space in row:
                line.append(space_ids.get(space))
            prettified_data.append(line)

        for row in prettified_data:
            print(" ".join(row))

Вы можете инициализировать и отобразить доска таким образом:

board = MazeData(data)
board.display()
...