如何撤消对 Python 2D 类实例数组所做的更改,例如在 C++ 中

Posted

技术标签:

【中文标题】如何撤消对 Python 2D 类实例数组所做的更改,例如在 C++ 中【英文标题】:How to undo change made to Python 2D array of class instances like in C++ 【发布时间】:2017-08-28 22:49:34 【问题描述】:
bool backtrack(int k)

    if (k >= bt.size())
        return true;
    int i = bt[k].first;
    int j = bt[k].second;
    // fast path - only 1 possibility
    if (cells[i][j].value)
        return backtrack(k + 1);
    auto constraints = cells[i][j].constraints;
    // slow path >1 possibility.
    // making snapshot of the state
    array<array<cell,9>,9> snapshot(cells);
    for (int v = 1; v <= 9; v++) 
        if (!constraints[v]) 
            if (set(i, j, v)) 
                if (backtrack(k + 1))
                    return true;
            
            // restoring from snapshot,
            cells = snapshot;
        
    
    return false;

我如何在 Python 中做同样的事情?现在我有这个,但它不工作。我正在制作深拷贝,但仍然没有给出相同的答案。 这里的 cells 是 Cell 实例的二维数组

def backtrack(self, k, bt, cells):
    if k == len(bt):
        return True      
    i = bt[k][0]
    j = bt[k][1]
    if cells[i][j].value:
        return self.backtrack(k+1, bt, cells)
    constraints = list(cells[i][j].constraints)
    deepcop = copy.deepcopy(cells)
    for v in range(1, 10):        
        if not constraints[v]:
            if self.set(i, j, v, cells):
                if self.backtrack(k + 1, bt, cells):
                    return True
            cells = deepcop
    return False

编辑:我已经添加了完整的功能。 C++ 使用全局变量,而我在 Python 中传递参数。 bt 是 C++ 中的对对象数组,它是 Python 中的元组数组。

【问题讨论】:

我相信你需要对每种类型进行深度复制,因为在 python 变量中存储对东西的引用(想想在 c++ 中传递指针) 你的缩进搞砸了,你在函数体之外有 return 语句。您是否遗漏了函数定义语句? @paul 谢谢。我编辑了我认为现在正确的问题。 【参考方案1】:

这两个程序不是等价的。在 C++ 版本中,这一行:

cells = snapshot;

全局变量cells标识的对象替换为局部变量snapshot标识的对象。

在 Python 版本中,这一行:

cells = deepcop

local 变量cells 标识的对象替换为局部变量deepcop 标识的对象。

这两种语言在处理函数参数方面非常相似。函数参数仅在函数体内作用域,并且任何函数都不会导致调用范围内的对象 被另一个对象替换。 (当参数是具有内部状态的对象时,该状态当然可以在函数体内更改。)

由于您使用的是在 Python 类中定义的函数(您使用 self 变量),请考虑将 cells 设为成员变量。

【讨论】:

嘿,非常感谢!由于在 Python 中对象是通过引用传递的,因此我认为它等同于使用全局/静态变量。这是针对多个测试用例和Solution 类的问题,因此当我完成cells 时必须创建一个新的Solution.cells 变量,因为所有测试用例都使用Solution 的静态cells

以上是关于如何撤消对 Python 2D 类实例数组所做的更改,例如在 C++ 中的主要内容,如果未能解决你的问题,请参考以下文章

撤消对 Clojure 中内置函数的覆盖

撤消或反向 argsort(),python

如何在 Python 中使用 BeautifulSoup 保存对 HTML 文件所做的更改?

撤消实体框架实体中的更改

如何撤消选定的提交

如何保存对 Python 列表所做的更改,以便在重新运行脚本后更新? [复制]