I have two pieces of python code that I expect to give me the same result but that is not happening. I wrote the following routine for a fill type question on leetcode and got the wrong answer
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
However when I changed it store the boolean values returned by the recursive call to the function in separate variables and take the AND at the end, my solution was accepted.
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
I am quite perplexed as I thought that they should have identical behavior. I am new to Python so I don't know if I'm missing anything obvious. Any help is appreciated.
CodePudding user response:
I am not entirely sure what that function is supposed to calculate, but note that and
is lazy, i.e. the 'right' expression is only evaluated if the 'left' expression is not already false. In your case this means that
val = val and self.processIsland(grid, proc, ip, jp)
will only execute the recursive call if val
is not already False
from an earlier iteration. And since those recursive calls have side-effect (e.g. they modify grid
and proc
) that might be a problem.
The second version, on the other hand, always executes all four recursive calls. If you want to make that a bit prettier, you can just return all(val)
though, instead of combining them with and
in the previous line.
CodePudding user response:
Understand the logical operators.
For logical AND: If the first operator is True then only it checks next operator Ex.
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.
Therefore your code does not makes recursive calls when val is False in first case.