Это рекурсивное решение. Рекурсивный означает, что функция решения сама вызывает. Он продолжает свой код, когда программа возвращается из вызова.
grid[y][x] = n # current solve changes grid
solve(grid) # call recursively solve
# the function solve has now returned
# and can have changed grid
grid[y][x] = 0 # now the current solve continues
Это работает, потому что список, такой как grid, является изменяемым объектом, что означает, что вызываемая функция может изменить сетку, и вызывающая сторона продолжает с измененной сеткой.
Существует одно условие: внутри решения должно быть какое-то условие, чтобы после многократного вызова самого себя возвращалось последнее вызванное решение.
Сравните это с хорошо известной функцией Фибоначчи:
def F(n):
if n == 0:
return 0
elif n == 1:
return 1
else:
return F(n - 1) + F(n - 2)
print(F(6))
Он перестает называть себя, когда n == 0 или n == 1. До этого он продолжает называть себя n-1 и n-2.