Difficulty understanding 'local variable referenced before assignment'

Viewed 175

There are a lot of posts with similar questions but even after going through them, I am unable to get the logic behind. Sorry, I have never programmed before. Below are two pieces of code - a recursive function for calculating the factorial. This gets an error 'local variable 'f' referenced before assignment' whether I pass 1 or any value.

def func(n):
    if n != 1:
        f = n*func(n-1)
    else:        
        return f

However, when I change the code to:

def func(n):
    if n == 1:
        return 1
    else:        
        f = n*func(n-1)

    return f

there's no error and the program runs. In both cases, I have not initialized the variable 'f' before assigning and both are local to the function only. Just trying to get my basic concepts cleared. Thanks.

2 Answers

Function 1 -

def func(n):
    if n != 1:
        f = n*func(n-1)
    else:        
        return f
  • In the first function, f might still be uninitialized ( depending on the input ) when you are returning it. Your first function doesn't have a base case as in the second one.
  • Suppose that your passed parameter n won't be equal to 1. The if n != 1 condition would be evaluated to False. Then how would else statement return f when it hasn't been initialsed yet? and hence the error...

Function 2 -

def func(n):
    if n == 1:
        return 1
    else:        
        f = n*func(n-1)    
    return f
  • However, in your second function, you will always either be initializing f before you return it ( n >= 1 ) or going into an infinite recursion( n < 1 ) . No matter what, you won't be returning it without initializing. So it gives no error.

Hope you understand why the error occurs.

Consider this function:

def func(n):
    return f

It trivially easy to see why this function would give an error since f doesn't exist.

In your first function, if n != 1 evaluates False, it will behave like the example function I gave above.

As @Mustafa Aydın commented the error is slightly different than your UnboundLocalError but the concept remains.

Related