繁体   English   中英

Python递归添加到类变量会产生不同的结果

[英]Python recursively adding to a class variable gives different results

class Perimeter:
    def __init__(self):
        super().__init__()
        self.count = 0
        self.grid = [[0, 0, 0, 0], [0, 1, 1, 0], [0, 1, 1, 0], [0, 0, 0, 0]]
        self.seen = set()

    def perimeter_calculator(self, x: int, y: int) -> int:

        if self.grid[x][y] == 0:
            print(f"count: {self.count}")
            return 1

        if (x, y) not in self.seen:
            self.seen.add((x, y))

            a = self.perimeter_calculator(x + 1, y)
            b = self.perimeter_calculator(x - 1, y)
            c = self.perimeter_calculator(x, y + 1)
            d = self.perimeter_calculator(x, y - 1)

            self.count += a + b + c + d
        return 0

if __name__ == "__main__":
    perm = Perimeter()
    perm.perimeter_calculator(1, 1)
    print(perm.count)
    assert perm.count == 8

我正在处理 leetcode 问题 463 “Island Perimeter”( https://leetcode.com/problems/island-perimeter/ ),并注意到在使用类变量时我无法解释的一些“Python”行为。

上面的函数创建了一个简单的 4x4 网格,中间有一个 2x2 岛。 我们从 (1, 1) 开始搜索,它应该给出 8 作为该岛的周长。 如果我像上面那样运行它,一切都很好,并且函数按预期返回 8。

但是,如果我像这样更改递归调用:

      self.count += self.perimeter_calculator(x + 1, y)
      self.count += self.perimeter_calculator(x - 1, y)
      self.count += self.perimeter_calculator(x, y + 1)
      self.count += self.perimeter_calculator(x, y - 1)

self.count 最后是 2,并且在递归调用中以某种方式减少(可以从打印输出中看到)。

为什么将self.perimeter_calculator()的结果直接分配给self.count而不是使用局部变量abcd作为临时存储时,结果会有所不同? Python“在幕后做什么”?

正如@ThierryLathuille 在 Python 聊天中提到的那样: https ://chat.stackoverflow.com/transcript/message/54642897#54642897 问题源于 Python 在调用函数时为类变量赋值的方式。 这是@Kevin 的一个更简单的例子,强调了这个问题:

class Fred:
    def __init__(self):
        self.value = 0
    def f(self):
        self.value += self.h()
        print(self.value)
    def g(self):
        x = self.h()
        self.value += x
        print(self.value)
    def h(self):
        self.value += 1
        return 2

Fred().f() #2
Fred().g() #3

当调用f()时,我们添加到self.value调用h()之前的值

调用g()时,我们使用调用h()后的值

当递归地执行此操作时(如在原始示例中),我假设 Python 会覆盖更深调用堆栈中的值,甚至导致self.count的值“减少”。

谢谢@ThierreLathuille 和@Kevin!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM