Search code examples
pythonlocal-variables

UnboundLocalError: local variable 'x' referenced before assignment for one variable whilst other works in Python


How come I get local variable referenced before assignment error for cur_max while i can use copy_matrix within the dfs function?

class Solution:
    def longestIncreasingPath(self, matrix: List[List[int]]) -> int:
        rows, columns = len(matrix), len(matrix[0])
        copy_matrix = {}
        cur_max = 0
        
        def dfs(r, c, prev):
            if (r < 0 or c < 0 or
                r == rows or c == columns or
                matrix[r][c] <= prev):
                return 0
            
            if (r, c) in copy_matrix:
                return copy_matrix[(r, c)]
            
            max_length = 0
            max_length = max(max_length, 1 + dfs(r + 1, c, matrix[r][c]))
            max_length = max(max_length, 1 + dfs(r - 1, c, matrix[r][c]))
            max_length = max(max_length, 1 + dfs(r, c + 1, matrix[r][c]))
            max_length = max(max_length, 1 + dfs(r, c - 1, matrix[r][c]))
            copy_matrix[(r, c)] = max_length
            cur_max = max(cur_max, copy_matrix[(r, c)])
            
            return max_length
        
        for r in range(rows):
            for c in range(columns):
                dfs(r, c, -1)
        
        return max(copy_matrix.values())

here's what i get

UnboundLocalError: local variable 'cur_max' referenced before assignment
    cur_max = max(cur_max, copy_matrix[(r, c)])
Line 22 in dfs (Solution.py)
    dfs(r, c, -1)
Line 28 in longestIncreasingPath (Solution.py)
    ret = Solution().longestIncreasingPath(param_1)
Line 49 in _driver (Solution.py)
    _driver()
Line 60 in <module> (Solution.py)

Solution

  • It is because for copy_matrix there is no local variable there, so it references the nonlocal variable present at line 6 ie copy_matrix = {}, while for cur_max it is being defined as a local variable in line 24 ie cur_max = max(cur_max, copy_matrix[(r, c)]), it is referencing nonlocal variables for copy_matirx, rows, columns but it is referencing the local variable for cur_max because it is being defined in the function and being referenced before assignment. What you probably want to do is this

    def dfs(r, c, prev):
        nonlocal cur_max
        if (r < 0 or c < 0 or
            r == rows or c == columns or
            matrix[r][c] <= prev):
            return 0
        
        if (r, c) in copy_matrix:
            return copy_matrix[(r, c)]
        
        max_length = 0
        max_length = max(max_length, 1 + dfs(r + 1, c, matrix[r][c]))
        max_length = max(max_length, 1 + dfs(r - 1, c, matrix[r][c]))
        max_length = max(max_length, 1 + dfs(r, c + 1, matrix[r][c]))
        max_length = max(max_length, 1 + dfs(r, c - 1, matrix[r][c]))
        copy_matrix[(r, c)] = max_length
        cur_max = max(cur_max, copy_matrix[(r, c)])
        
        return max_length
    

    read more