variable not defined even after setting as global (Python) + How do I approach such cases?

Question:

I have a recursive function which computes some answer at the end and I have to store the maximum of these temporary answers and return it.

The code is as follows.
(If you know this, I am not worried about Kadane’s Algorithm, I wanted to know how to get this done)

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        
        ans = nums[0]
        
        def helper(n):
            
            global ans

            if(n == 1):
                return nums[0]
            
            temp = max(nums[n-1], nums[n-1]+helper(n-1))
            
            ans = max(ans, temp) ### how do I do this? ###
            
            return temp
        
        helper(len(nums))
        return ans

The error I get is:
NameError: name 'ans' is not defined

How do I store the maximum value and return it in such cases? Since this doesn’t work.

Asked By: Adarsh Naidu

||

Answers:

You need to declare a global in the same function as the variable declaration itself because right now you are trying to set a global for a variable that is outside of the nested function’s scope.

The following code should work:

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        
    global ans
    ans = nums[0]
    
    def helper(n):
        
        global ans
        if(n == 1):
            return nums[0]
        
        temp = max(nums[n-1], nums[n-1]+helper(n-1))
        
        ans = max(ans, temp) ### how do I do this? ###
        
        return temp
    
    helper(len(nums))
    return and

do keep in mind you must put global ans not just when you define the variable, but in every function that you wish to assign to the variable.

Answered By: 3ddavies

you have to add global ans twice in the first function and in the second.
with your code:

class Solution:
def maxSubArray(self, nums: List[int]) -> int:

    global ans

    ans = nums[0]
    
    def helper(n):
        
        global ans

        if(n == 1):
            return nums[0]
        
        temp = max(nums[n-1], nums[n-1]+helper(n-1))
        
        ans = max(ans, temp) ### how do I do this? ###
        
        return temp
    
    helper(len(nums))
    return ans
Answered By: Zitstoel

This is the perfect use case for the nonlocal keyword!
This keyword allows you to refer to the ans variable in the enclosing function.

Solution (simply replace global with nonlocal):

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        
        ans = nums[0]
        
        def helper(n):
            
            nonlocal ans

            if(n == 1):
                return nums[0]
            
            temp = max(nums[n-1], nums[n-1]+helper(n-1))
            
            ans = max(ans, temp) ### how do I do this? ###
            
            return temp
        
        helper(len(nums))
        return ans
Answered By: lpeak

many have already answered You need to use nonlocal instead of global. let me just try to explain why you need to do so.

"nonlocal" means that a variable is "neither local nor global", i.e, the variable is from an enclosing namespace (typically from an outer function of a nested function as it happens to be your case)

To explain the difference between nonlocal and global I would say that the nonlocal variable must have been already bound in the enclosing namespace (otherwise a syntax error will be raised) while a global declaration in a local scope does not require the variable to be pre-bound (it will create a new binding in the global namespace if the variable is not pre-bound).

Answered By: Naresh Joshi
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.