Python 布尔变量不在循环内更新

Python boolean variable not updating within a loop

我有两段 python 代码,我希望它们能给我相同的结果,但并没有发生。我在leetcode上写了一道填空题的例程,结果答错了

def processIsland(self, grid: List[List[int]], proc: List[List[int]], i: int, j: int) -> bool:
    n = len(grid)
    m = len(grid[0])
    proc[i][j] = 1
    trav = [0, 1, 0, -1, 0]
    val = True
    for k in range(4):
        ip = i+trav[k]
        jp = j+trav[k+1]
        if 0 <= ip < n and 0 <= jp < m:
            if grid[ip][jp] == 0 and proc[ip][jp] == 0:
                val = val and self.processIsland(grid, proc, ip, jp)         
    if i == 0 or i == n-1 or j == 0 or j == m-1:
        return False
    return val

然而,当我更改它时,它将递归调用函数返回的布尔值存储在单独的变量中,并在最后使用 AND,我的解决方案被接受了。

def processIsland(self, grid: List[List[int]], proc: List[List[int]], i: int, j: int) -> bool:
    n = len(grid)
    m = len(grid[0])
    proc[i][j] = 1
    trav = [0, 1, 0, -1, 0]
    val = [True, True, True, True]
    for k in range(4):
        ip = i+trav[k]
        jp = j+trav[k+1]
        if 0 <= ip < n and 0 <= jp < m:
            if grid[ip][jp] == 0 and proc[ip][jp] == 0:
                val[k] = self.processIsland(grid, proc, ip, jp)         
    if i == 0 or i == n-1 or j == 0 or j == m-1:
        return False
    val = val[0] and val[1] and val[2] and val[3]
    return val

我很困惑,因为我认为他们应该有相同的行为。我是 Python 的新手,所以我不知道我是否遗漏了任何明显的东西。感谢任何帮助。

我不完全确定该函数应该计算什么,但请注意 and 是惰性的,即 'right' 表达式仅在 'left' 表达式不计算时计算已经是假的。在您的情况下,这意味着

val = val and self.processIsland(grid, proc, ip, jp)

将仅在 val 尚未从较早的迭代中 False 时执行递归调用。由于这些递归调用具有 side-effect(例如,它们修改了 gridproc),这可能是个问题。

另一方面,第二个版本总是执行所有四个递归调用。如果你想让它更漂亮一点,你可以 return all(val) 不过,而不是将它们与上一行中的 and 结合起来。

了解逻辑运算符。

For logical AND:如果第一个运算符为真,则仅检查下一个运算符 例如

    def hello():
        print("Hello")

    def world():
        print("World")

    a = True
    b = False

    c = a and hello()
    c = b and world()

    Output: Hello
    Explanation:
             a is true therefore hello() function is executed.
             b is false therefore world() function is not executed.

因此,当 val 在第一种情况下为 False 时,您的代码不会进行递归调用。