Как более эффективно распечатать сетку судоку

#python #python-3.x #list-comprehension

Вопрос:

Я программирую игру Судоку в терминале, я хочу распечатать сетку для консоли с квадратом вокруг нее, как на рисунке ниже. С моим кодом нет никаких проблем, кроме того, что он неэффективен.

Я хотел бы сделать его более эффективным и коротким (с пониманием списка, умножением строк и т. Д.). плата определяется следующим образом: плата = [[_ для _ в диапазоне(9)] для _ в диапазоне(9)]

Это функция, которую я использую:

 def Print_Board(board):

    print("n-------------------------")

    for i in range(9):
        for j in range(9):
            if board[i][j] is not None:
                if j == 0:
                    print("|", end=" ")
                print(f"{board[i][j]} ", end="")
            if (j   1) % 3 == 0:
                print("|", end=" ")
        if (i   1) % 3 == 0:
            print("n-------------------------", end=" ")
        print()
 

введите описание изображения здесь

Комментарии:

1. Если вы не печатаете это тысячи раз, оптимизация не приведет к значительному повышению производительности.

2. Не используйте _ в качестве имени переменной, если вы на самом деле используете ее значение.

3. Я думаю, что sys.stdout работает быстрее, чем обычная печать, хотя разница не будет заметна, если вы не напечатаете чрезвычайно большое количество судоку, чего, я думаю, вы не сделаете. Я согласен с Нитеей.

4. Как правило, минимизируйте количество print() s. В идеале создайте полное строковое представление вашего игрового поля и сразу же распечатайте его. Кроме того, поскольку ваши реальные цифры будут другими, вопрос, как он был задан, бесполезен. Сначала вы должны рассмотреть, какая структура данных содержит игровое поле, а затем спросить, как его распечатать.

Ответ №1:

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

 bar = '-------------------------n'
lnf = '|'  (' {:}'*3   ' |')*3   'n'
bft = bar   (lnf*3 bar)*3
print(bft.format(*(el for rw in board for el in rw)))
 

Конечно, вам нужно создать формат только один раз. После этого это просто отпечаток.



Предложение от JonSG в комментариях, чтобы инкапсулировать это в закрытие:

 def make_board_printer():
    bar = '-------------------------n'
    lnf = '|'  (' {:}'*3   ' |')*3   'n'
    bft = bar   (lnf*3 bar)*3
    return (lambda bd:print(bft.format(*(el for rw in bd for el in rw))))
 

является функцией, которая возвращает функцию принтера платы:

 # make a printer:
b_print = make_board_printer()

# then as needed
b_print(board)
 

Комментарии:

1. Если бы я действительно играл в гольф, планка тоже была бы умножением :-).

2. Вы должны добавить расширенный ответ, который использует замыкание для построения шаблона и возвращает лямбду для печати с ним.

3. Боже, мне так нравится этот ответ. Не только потому, что она короткая и приятная, но и потому, что она концептуально великолепна. Создание шаблона печати, который можно использовать повторно, выводит ввод-вывод из функции форматирования и, что не менее важно, приводит к одному вызову функции печать(). Отличная работа.

Ответ №2:

Ты мог бы сделать это:

 def print_board(board):
    print("n-------------------------")
    for row_num, row in enumerate(board):
        print("|", end=" ")
        for col_num, item in enumerate(row):
            print(item, end=" ")
            if (col_num   1) % 3 == 0:
                print("|", end=" ")
        if (row_num   1) % 3 == 0:
            print("n-------------------------", end=" ")
        print()


if __name__ == '__main__':
    print_board(board=[range(9) for _ in range(9)])
 

Ответ №3:

Вот (не более читаемое) решение вашей проблемы:

 board = [range(1,10) for i in range(9)]
print("-"*25)
for idx, row in enumerate(board):
    rowStr = " | ".join([" ".join(map(str, row[i:i 3])) for i in range(0, len(row), 3)])
    print(f'| {rowStr} |')
    if (idx 1) % 3 == 0:
        print("-"*25)
 

Выход:

 -------------------------
| 1 2 3 | 4 5 6 | 7 8 9 |
| 1 2 3 | 4 5 6 | 7 8 9 |
| 1 2 3 | 4 5 6 | 7 8 9 |
-------------------------
| 1 2 3 | 4 5 6 | 7 8 9 |
| 1 2 3 | 4 5 6 | 7 8 9 |
| 1 2 3 | 4 5 6 | 7 8 9 |
-------------------------
| 1 2 3 | 4 5 6 | 7 8 9 |
| 1 2 3 | 4 5 6 | 7 8 9 |
| 1 2 3 | 4 5 6 | 7 8 9 |
-------------------------