Backback de N-queen en Python: ¿cómo devolver soluciones en lugar de imprimirlas?

def solve(n):
    #prepare a board
    board = [[0 for x in range(n)] for x in range(n)]
    #set initial positions
    place_queen(board, 0, 0)

def place_queen(board, row, column):
    """place a queen that satisfies all the conditions"""
    #base case
    if row > len(board)-1:
        print board
    #check every column of the current row if its safe to place a queen
    while column < len(board):
        if is_safe(board, row, column):
            #place a queen
            board[row][column] = 1
            #place the next queen with an updated board
            return place_queen(board, row+1, 0)
        else:
            column += 1
    #there is no column that satisfies the conditions. Backtrack
    for c in range(len(board)):
        if board[row-1][c] == 1:
            #remove this queen
            board[row-1][c] = 0
            #go back to the previous row and start from the last unchecked column
            return place_queen(board, row-1, c+1)

def is_safe(board, row, column):
    """ if no other queens threaten a queen at (row, queen) return True """
    queens = []
    for r in range(len(board)):
        for c in range(len(board)):
            if board[r][c] == 1:
                queen = (r,c)
                queens.append(queen)
    for queen in queens:
        qr, qc = queen
        #check if the pos is in the same column or row
        if row == qr or column == qc:
            return False
        #check diagonals
        if (row + column) == (qr+qc) or (column-row) == (qc-qr):
            return False
    return True

solve(4)

Escribí el código de Python para el problema N-queen e imprime todas las soluciones posibles cada vez que se encuentra. Sin embargo, me gustaría modificar este código para que devuelva una lista de todas las soluciones (configuraciones de placa) en lugar de imprimirlas. Intenté modificar el código como sigue:

def solve(n):
    #prepare a board
    board = [[0 for x in range(n)] for x in range(n)]
    #set initial positions
    solutions = []
    place_queen(board, 0, 0, solutions)

def place_queen(board, row, column, solutions):
    """place a queen that satisfies all the conditions"""
    #base case
    if row > len(board)-1:
        solutions.append(board)
        return solutions
    #check every column of the current row if its safe to place a queen
    while column < len(board):
        if is_safe(board, row, column):
            #place a queen
            board[row][column] = 1
            #place the next queen with an updated board
            return place_queen(board, row+1, 0, solutions)
        else:
            column += 1
    #there is no column that satisfies the conditions. Backtrack
    for c in range(len(board)):
        if board[row-1][c] == 1:
            #remove this queen
            board[row-1][c] = 0
            #go back to the previous row and start from the last unchecked column
            return place_queen(board, row-1, c+1, solutions)

Sin embargo, esto vuelve tan pronto como se encuentra la primera solución, por lo quesolutions solo consta de una posible configuracion de placa. Ya queimprimir vs. devolver Me ha estado confundiendo con los algoritmos de seguimiento, me gustaría mucho que alguien me mostrara cómo modificar el código anterior y cómo abordar problemas similares en el futuro.

Supongo que usar una variable global funcionaría, pero aprendí de alguna parte que se desaconseja el uso de variables globales para este problema. ¿Podría alguien explicar esto también?

EDITAR:

def solve(n):
    #prepare a board
    board = [[0 for x in range(n)] for x in range(n)]
    #set initial positions
    solutions = list()
    place_queen(board, 0, 0, solutions)
    return solutions

def place_queen(board, row, column, solutions):
    """place a queen that satisfies all the conditions"""
    #base case
    if row > len(board)-1:
        #print board
        solutions.append(deepcopy(board)) #Q1
    #check every column of the current row if its safe to place a queen
    while column < len(board):
        if is_safe(board, row, column):
            #place a queen
            board[row][column] = 1
            #place the next queen with an updated board
            return place_queen(board, row+1, 0, solutions) #Q2
        else:
            column += 1
    #there is no column that satisfies the conditions. Backtrack
    for c in range(len(board)):
        if board[row-1][c] == 1:
            #remove this queen
            board[row-1][c] = 0
            #go back to the previous row and start from the last unchecked column
            return place_queen(board, row-1, c+1, solutions) #Q3

Lo anterior devuelve todas las soluciones encontradas en lugar de imprimirlas. Tengo algunas preguntas más (las partes relacionadas están marcadas como Q1 y Q2 en el código anterior)

¿Por qué necesitamossolutions.append(deepcopy(board))? En otras palabras, ¿qué está sucediendo exactamente cuando lo hacemos?solutions.append(board) y por qué esto lleva a añadir la placa inicial que es[[0,0,0,0] ...]?¿Por qué nos encontramos con un problema cuandoreturn place_queen(board, row+1, 0) es reemplazado porplace_queen(board, row+1, 0)? En realidad no estamos devolviendo nada (oNone), pero sinreturn La lista sale de índice.

Respuestas a la pregunta(2)

Su respuesta a la pregunta