将值追加到 Python 成员变量

我是Python和OO编程的新手,所以请原谅,可能,设计得非常糟糕的代码(任何提示将不胜感激)。


在这个,人为的,MWE,这纯粹是为了说明我的更大项目中的类似问题。我想遍历3x3网格并填充它,以便它包含所有数字1-9,我唯一可以更改的值是当前设置为0的值。即,如果网格当前具有数字1-7并且两个位置为0,则其中一个0变为8,一个变为9,在这种情况下,有两个解决方案,因为8和9的顺序也可以交换。


我设计了一个回溯求解器(runSolver()),它确实解决了这个问题,我正在努力做的是在到达解决方案时存储它们。我已经添加了一个 print 语句,用于在达到解决方案时,这会按预期打印出解决方案,然后我尝试将此解决方案追加到列表中,而不是追加刚刚找到的解决方案,而是追加初始的,未解决的网格。


class Grid:


    def __init__(self):

        self.grid = np.zeros((3, 3))


    def writeGrid(self, grid):

        self.grid = grid


    def printGrid(self):

        print(self.grid)


    def getValue(self, col, row):

        return self.grid[row][col]


    def setValue(self, col, row, num):

        self.grid[row][col] = num



class Solver:


    def __init__(self, grid):

        self.grid = grid

        self.solutions = []

        self.n_solutions = 0


    def isValid(self, num):

        for i in range(3):

            for j in range(3):

                if self.grid.getValue(i, j) == num:

                    return False

        return True


    def runSolver(self):

        for row in range(3):

            for col in range(3):

                if (self.grid.getValue(col, row)) == 0:

                    for num in range(1,10):

                        if self.isValid(num):

                            self.grid.setValue(col, row, num)

                            self.runSolver()

                            self.grid.setValue(col, row, 0)

                    return

        self.grid.printGrid()             # this line prints the actual solutions when reached (it works)

        self.solutions.append(self.grid)  # this should append the solution to 'solutions'

        self.n_solutions += 1             # keeps track of how many solutions there are

实际显示问题的主要功能是,


# Set up game

gameGrid = Grid()

gameGrid.writeGrid([[1, 4, 5],

                    [0, 6, 0],

                    [7, 8, 9]])

solverGrid = Solver(gameGrid)


# Run the solver

solverGrid.runSolver()


从一些在线搜索中,我认为我可能会混淆实例属性和类属性以及它们可访问的范围,但我真的不确定。


炎炎设计
浏览 92回答 1
1回答

冉冉说

当您运行时,您基本上只需附加对 to 的引用。因此,在末尾,您有一个引用列表,因为它们都指向同一个对象。self.solutions.append(self.grid)self.gridself.solutionsrunSolverself.solutions这与对象和Numpy数组都是可变对象的事实有关。与 Python 字符串相反,例如,当您修改它们(例如)时,相同的对象将就地修改,而不是创建新对象。Gridself.grid.setValue(col, row, num)下面是用列表列表说明的相同问题:>>> l = []>>> x = [1]>>> l.append(x)>>> l[[1]]>>> x.append(2)>>> l.append(x)>>> l[[1, 2], [1, 2]]每次添加网格时,都必须创建网格的副本,以便可以像当时一样获得网格的“快照”。self.solutions你可以做这样的事情:class Grid:    def __init__(self, grid=None):        if grid == None:            self.grid = np.zeros((3, 3))        else:             # Copy the array, otherwise we'll have the same mutability issue as above.            self.grid = np.copy(grid)在:runSolver        grid_copy = Grid(self.grid.grid)        self.solutions.append(grid_copy) # this should append the solution to 'solutions'
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python