为了账号安全,请及时绑定邮箱和手机立即绑定

将值追加到 Python 成员变量

将值追加到 Python 成员变量

炎炎设计 2022-09-06 19:49:35
我是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] = numclass 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 gamegameGrid = Grid()gameGrid.writeGrid([[1, 4, 5],                    [0, 6, 0],                    [7, 8, 9]])solverGrid = Solver(gameGrid)# Run the solversolverGrid.runSolver()从一些在线搜索中,我认为我可能会混淆实例属性和类属性以及它们可访问的范围,但我真的不确定。
查看完整描述

1 回答

?
冉冉说

TA贡献1877条经验 获得超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'



查看完整回答
反对 回复 2022-09-06
  • 1 回答
  • 0 关注
  • 91 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信