0

The following function returns none instead of 1 at the base case, why is this?

def test(num):
  if(num == 1):
    print('our num is:',num)
    return num
  else:
    print(num)
    num -= 1
    test(num)
print(test(5))
  • if you don't use `return 1` (or similar) then it will return `None` as default value. – furas Apr 19 '20 at 00:57
  • Good question! Why the negative votes? – tdelaney Apr 19 '20 at 00:59
  • 1
    Remember that the `return num` is several levels deep in the call stack. You need to propegate that back to the original caller. `return test(num)` – tdelaney Apr 19 '20 at 01:00
  • BTW: you have recursion and `return num` sends result to place where you use `test(num)` but it will not send `num` back to previous `test(num)` without `return` – furas Apr 19 '20 at 01:00
  • 1
    Does this answer your question? [Why does my recursive function return None?](https://stackoverflow.com/questions/17778372/why-does-my-recursive-function-return-none) – AMC Apr 19 '20 at 01:01

4 Answers4

1

Because you're not returning anything under the else. See the below code as a fix.

def test(num):
  if(num == 1):
    print('our num is:',num)
  else:
    print(num)
    num -= 1
    test(num)

  return num

print(test(5))
trdwll
  • 79
  • 2
  • 6
1

You just forgot to return num to fix it:

def test(num):
  if(num == 1):
    print('our num is:',num)
    return num
  else:
    print(num)
    num -= 1
    return test(num)

then running print(test(5)) will return 1.

Sanjit Sarda
  • 381
  • 1
  • 4
  • 13
1

Actually, it very much returns 1 at the base case. The problem is that you don't propagate that up the call stack when returning through all the recursive layers, as in the following graphic where you call it with 3:

Caller
|    ^
|    |
|  (None)
v    |
test(3) <-----+
 |            |
 |          (None)
 |            |
 +-----> test(2) <-----+
          |            |
          |           (1)
          |            |
          +-----> test(1)

In this case:

  • you call test(3);
  • it calls test(2);
  • it calls test(1), which returns 1 to `test(2);
  • test(2) then returns None to `test(3);
  • test(3) returns None to the caller.

When you come out of the base case, you've returned 1. You then return nothing explicit up to the next layer, which means Python will implicitly return None.

The only case in which you'll get 1 out of your current code is if you call the base case directly, with test(1).

Fixing that, and making some readability improvements, would be done thusly (comments are to explain my reasoning for change, they don't belong in the real code):

def test(num):
    # Handle pathological case of passing in something < 1.

    if num <= 1:
        # Will always print 1 so not sure why it's needed.
        print('our num is:',num)
        return num

    # No need for else since above if bit returns anyway.

    print(num)
    return test(num - 1) # just pass (num - 1) directly, and propagate.
paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
0

You return nothing in else. Try this.

def test(num):
  if(num == 1):
    print('our num is:',num)
    return num
  else:
    print(num)
    num -= 1
    return test(num)
LaoDa581
  • 563
  • 4
  • 18