![](/img/trans.png)
[英]Python - changing the variable inside for-loop gives different results
[英]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
而不是使用局部变量a
、 b
、 c
和d
作为临时存储时,结果会有所不同? 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.