无法创建实例变量的副本 (Python)
Unable to create a copy of an instance variable (Python)
我在python中创建了一个数独class,我想解决棋盘,并且还保留了与原始棋盘的实例变量,但是当我使用solve()
方法时,使用递归回溯算法 self.board
与 self.solved_board
一起更改,为什么会这样,我如何保留原始副本的变量?
grid = [ [3, 0, 6, 5, 0, 8, 4, 0, 0],
[5, 2, 0, 0, 0, 0, 0, 0, 0],
[0, 8, 7, 0, 0, 0, 0, 3, 1],
[0, 0, 3, 0, 1, 0, 0, 8, 0],
[9, 0, 0, 8, 6, 3, 0, 0, 5],
[0, 5, 0, 0, 9, 0, 6, 0, 0],
[1, 3, 0, 0, 0, 0, 2, 5, 0],
[0, 0, 0, 0, 0, 0, 0, 7, 4],
[0, 0, 5, 2, 0, 6, 3, 0, 0] ]
class Sudoku:
def __init__(self, board):
self.board = board
self.solved_board = board[:] #<--- I used the [:] because I thought this will create a new list
def get_board(self):
return self.board
def set_board(self, board):
self.board = board
self.solved_board = board
def print_original_board(self):
self.print(self.board)
def print_solved_board(self):
self.print(self.solved_board)
def print(self, board):
"""Receiving a matrix and printing a board with seperation"""
for i in range(len(board)):
if i % 3 == 0 and i!=0:
print('---------------------------------')
for j in range(len(board[i])):
if j%3==0 and j!=0:
print(" | ", end='')
print(" " + str(board[i][j]) + " ", end='')
print('')
def find_empty(self,board):
"""Receiving a matrix, loops through it, and return a tuple
with the row and the column of the free stop in the matrix"""
for i in range(len(board)):
for j in range(len(board[i])):
if board[i][j]==0:
return (i,j)
return None
def is_valid(self, board, num, pos):
"""Receiving matrix, a number we want to insert, and a tuple with the row and col
and will check if the row, col, and box are valid so we can place the number
in the position"""
# Check row
for i in range(len(board[pos[0]])):
if pos[0] != i and board[pos[0]][i] == num:
return False
# Check col
for i in range(len(board)):
if pos[1] != i and board[i][pos[1]] == num:
return False
pos_row = pos[0] // 3
pos_col = pos[1] // 3
for i in range(pos_row*3 ,pos_row*3 + 3):
for j in range(pos_col * 3, pos_col*3 + 3):
if (i,j) != pos and board[i][j] == num:
return False
return True
def solve(self):
"""Using backtracking algorithm to solve the solved_board variable"""
find = self.find_empty(self.solved_board)
if not find:
return True
else:
row, col = find
for i in range(1,10):
if(self.is_valid(self.solved_board, i, (row, col))):
self.solved_board[row][col] = i
if self.solve():
return self.solved_board
self.solved_board[row][col] = 0
return False
sudoku = Sudoku(grid)
sudoku.print_original_board()
print(" ")
sudoku.solve()
sudoku.print_original_board() # <---- This prints the solved board
是的,board[:]
确实创建了一个新列表 -- 所有这些旧的内部列表:
In [23]: board = [[1], [2]]
In [24]: board2 = board[:]
In [25]: board2[0] is board[0]
Out[25]: True
In [26]: board2[0][0] += 10
In [28]: board
Out[28]: [[11], [2]]
你需要深拷贝它;例如,
solved_board = [row[:] for row in board]
self.solved_board = board[:]
确实创建了一个新列表,但它引用了与 board
相同的内部列表。您需要更深入一层:
self.solved_board = [row[:] for row in board]
试试深拷贝方法
from copy import deepcopy
def __init__(self, board):
self.board = board
self.solved_board = deepcopy(board)
我在python中创建了一个数独class,我想解决棋盘,并且还保留了与原始棋盘的实例变量,但是当我使用solve()
方法时,使用递归回溯算法 self.board
与 self.solved_board
一起更改,为什么会这样,我如何保留原始副本的变量?
grid = [ [3, 0, 6, 5, 0, 8, 4, 0, 0],
[5, 2, 0, 0, 0, 0, 0, 0, 0],
[0, 8, 7, 0, 0, 0, 0, 3, 1],
[0, 0, 3, 0, 1, 0, 0, 8, 0],
[9, 0, 0, 8, 6, 3, 0, 0, 5],
[0, 5, 0, 0, 9, 0, 6, 0, 0],
[1, 3, 0, 0, 0, 0, 2, 5, 0],
[0, 0, 0, 0, 0, 0, 0, 7, 4],
[0, 0, 5, 2, 0, 6, 3, 0, 0] ]
class Sudoku:
def __init__(self, board):
self.board = board
self.solved_board = board[:] #<--- I used the [:] because I thought this will create a new list
def get_board(self):
return self.board
def set_board(self, board):
self.board = board
self.solved_board = board
def print_original_board(self):
self.print(self.board)
def print_solved_board(self):
self.print(self.solved_board)
def print(self, board):
"""Receiving a matrix and printing a board with seperation"""
for i in range(len(board)):
if i % 3 == 0 and i!=0:
print('---------------------------------')
for j in range(len(board[i])):
if j%3==0 and j!=0:
print(" | ", end='')
print(" " + str(board[i][j]) + " ", end='')
print('')
def find_empty(self,board):
"""Receiving a matrix, loops through it, and return a tuple
with the row and the column of the free stop in the matrix"""
for i in range(len(board)):
for j in range(len(board[i])):
if board[i][j]==0:
return (i,j)
return None
def is_valid(self, board, num, pos):
"""Receiving matrix, a number we want to insert, and a tuple with the row and col
and will check if the row, col, and box are valid so we can place the number
in the position"""
# Check row
for i in range(len(board[pos[0]])):
if pos[0] != i and board[pos[0]][i] == num:
return False
# Check col
for i in range(len(board)):
if pos[1] != i and board[i][pos[1]] == num:
return False
pos_row = pos[0] // 3
pos_col = pos[1] // 3
for i in range(pos_row*3 ,pos_row*3 + 3):
for j in range(pos_col * 3, pos_col*3 + 3):
if (i,j) != pos and board[i][j] == num:
return False
return True
def solve(self):
"""Using backtracking algorithm to solve the solved_board variable"""
find = self.find_empty(self.solved_board)
if not find:
return True
else:
row, col = find
for i in range(1,10):
if(self.is_valid(self.solved_board, i, (row, col))):
self.solved_board[row][col] = i
if self.solve():
return self.solved_board
self.solved_board[row][col] = 0
return False
sudoku = Sudoku(grid)
sudoku.print_original_board()
print(" ")
sudoku.solve()
sudoku.print_original_board() # <---- This prints the solved board
是的,board[:]
确实创建了一个新列表 -- 所有这些旧的内部列表:
In [23]: board = [[1], [2]]
In [24]: board2 = board[:]
In [25]: board2[0] is board[0]
Out[25]: True
In [26]: board2[0][0] += 10
In [28]: board
Out[28]: [[11], [2]]
你需要深拷贝它;例如,
solved_board = [row[:] for row in board]
self.solved_board = board[:]
确实创建了一个新列表,但它引用了与 board
相同的内部列表。您需要更深入一层:
self.solved_board = [row[:] for row in board]
试试深拷贝方法
from copy import deepcopy
def __init__(self, board):
self.board = board
self.solved_board = deepcopy(board)