2

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.

Anu
  • 23
  • 5
  • 3
    In the first example where does the value of `f` come from if `n != 1`? – Mark Jun 09 '20 at 20:12
  • 4
    Think about what happens in the first example if you go into the `else` branch. In that case, when you `return f` it isn't defined. In the second example, the `if` branch returns, and the `else` branch assigns `f`, so you can never reach `return f` without `f` being defined – juanpa.arrivillaga Jun 09 '20 at 20:12
  • In the second program you have two choices, one that returns with `1` (where `f` is not needed) and in the other one you do assign `f`. A `return` statement immediately terminates the function, so no other variables or statements are checked. – Jan Jun 09 '20 at 20:12
  • If n==1, what does your first `func(N)` return? Has `f` been assigned to at that point in the flow of execution? – DisappointedByUnaccountableMod Jun 09 '20 at 20:13
  • Actually, error message is pretty informative. You can add `f = 1` at the start of function, it'll work as well. – Olvin Roght Jun 09 '20 at 20:13
  • Related: [UnboundLocalError: local variable referenced before assignment when reading from file](https://stackoverflow.com/q/15367760/4518341) - also about a local variable that's undefined under certain conditions. – wjandrea Jun 09 '20 at 20:33

2 Answers2

1

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.

Community
  • 1
  • 1
Abhishek Bhagate
  • 5,583
  • 3
  • 15
  • 32
0

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.

noslenkwah
  • 1,702
  • 1
  • 17
  • 26