Python class 范围在嵌套递归函数中丢失

Python class scope lost in nested recursion function

当我尝试在 python class 中编写递归嵌套函数时,每次递归函数完成并 return 返回到我的第一个函数 class 属性恢复原状

def main():
    input = [
        [1,3,1],
        [1,5,1],
        [4,2,1]
    ]
    sln = Solution()
    sln.findPath(input)
    print("Output: " + str(sln.minPathSum))
    print(*sln.minPath, sep = "->")

class Solution():
    minPath = []
    minPathSum = None
    grid = []

    def findPath(self, grid):
        self.minPath = []
        self.minPathSum = None
        self.grid = grid
        self.recurse(0,0,[])

    def recurse(self, xCoord, yCoord, currentPath):
        if(len(self.grid) <= yCoord):
            return
        if(len(self.grid[yCoord]) <= xCoord):
            return

        currentValue = self.grid[yCoord][xCoord]
        currentPath.append(currentValue)

        if(len(self.grid) - 1 == yCoord and len(self.grid[yCoord]) - 1 == xCoord):
            currentPathSum = sum(currentPath)
            if(self.minPathSum == None or currentPathSum < self.minPathSum):
                self.minPathSum = currentPathSum
                self.minPath = currentPath
        else:
            #right
            self.recurse(xCoord + 1, yCoord, currentPath)
            #down
            self.recurse(xCoord, yCoord + 1, currentPath)

        currentPath.pop()
        return

if __name__ == "__main__":
    main()

运行 这导致:​​

Output: 7

调试 VSCode 中的代码确实表明 self.minPath 正在递归函数中设置;但是,它似乎正在失去原始 class 实例的范围。

此外,我尝试用单独的代码重新创建相同的嵌套情况,结果如下。

def main():
    tst = ScopeTest()
    tst.run()
    print(*tst.tstArray)
    print(tst.tstNumber)

class ScopeTest():
    tstArray = []
    tstNumber = 0

    def run(self):
        self.otherFunc()

    def otherFunc(self):
        self.tstArray = [1,2,3,4,5]
        self.tstNumber = 7

if __name__ == "__main__":
    main()

以上 return 预期结果使我认为这与递归有关。

请注意,我是 python 的新手,所以我可能犯了一个菜鸟错误,但我似乎无法弄清楚为什么会这样。

您的 recurse() 方法正在生成一个 currentPath 参数,当这被认为是正确的时,您执行:self.minPath = currentPath。不幸的是,您只是引用了与 currentPath 相同的对象,该对象后来发生了变异。

你的台词应该是:self.minPath = currentPath[:]

然后您会在 self.minPath

中看到一些内容

强制性 link 至 Ned Batchelder

您也可以删除这些行:

minPath = []
minPathSum = None
grid = []

从正下方 class Solution():