1

I'm working on a fairly basic function, and I'm finding it difficult to figure out why I get my output.

def mystery(n):    
    print(n)     
    if n < 4:     
        mystery(n + 1)    
    print(n)        

mystery(1)

This is my output:

1
2
3
4
4
3
2
1

I think I am clear on the first part of the output , n < 4 so we are adding 1 each time, then when we get to 4, the function skips the if part and prints(n) which is 4 again. I'm then a bit lost though why the output counts back down to 1. I'm guessing there is some really obvious part of recursion that I am overlooking, thanks for your help.

4
  • Because you have a second print statement after the recursive call returns. Commented Mar 17, 2019 at 13:03
  • When the function 'terminates' (mystery), it goes back into the previous function it came from, and does the second print.
    – IMCoins
    Commented Mar 17, 2019 at 13:03
  • It skips the if part because the condition 4 < 4 is false. Then, since every previous call of your mystery function has been completed in the if condition, it continues the program flow in the next line which is the last print(n), printing all values from 3 to 1.
    – Vasilis G.
    Commented Mar 17, 2019 at 13:04
  • I thought I'd seen this question before... : stackoverflow.com/questions/54905180 (10k+) Commented Mar 17, 2019 at 13:56

4 Answers 4

1

Every time mystery(n + 1) finishes, the next print(n) is called.

Maybe the following code is more clear:

def mystery(n):
    print('\t' * n + 'enter mystery ' + str(n))
    if n < 4:
        print('\t' * n + 'before mystery(n+1) ' + str(n))
        mystery(n + 1)
    print('\t' * n + 'after mystery ' + str(n))

mystery(1)

Output:

enter mystery 1
before mystery(n+1) 1
    enter mystery 2
    before mystery(n+1) 2
        enter mystery 3
        before mystery(n+1) 3
            enter mystery 4
            after mystery 4
        after mystery 3
    after mystery 2
after mystery 1
1

Think about it as a call tree:

mystery(1)
  print(1) - first print
  mystery(1 + 1 = 2)
    print(2) - first print
    mystery(2 + 1 = 3)
      print(3) - first print
      mystery(3 + 1 = 4)
        print(4) - first print
        print(4) - second print
      print(3) - second print
    print(2) - second print
  print(1) - second print

The first print of the function is invoked every time, showing the numbers counting up. But once you hit 4, the function no longer calls itself (it's the "terminating condition"), and then the call tree starts to unwind. In the case of n=4, it skips calling mystery() again and prints. Then the function returns to the previous call (which was mystery(3), prints, and then exits). This continues until everything is unwound and the program exits.

0

Just to help OP visualise what is happening, a couple of print statements can show how the actual flow of the code goes:

def mystery(n):    
    print(f"First print: {n}")
    if n < 4:
        print(f"n < 4 == True, n: {n}")
        mystery(n + 1)
    else:
        print(f"n < 4 == False, n: {n}")
    print(f"Second print: {n}")

mystery(1)

Output:

First print: 1
n < 4 == True, n: 1
First print: 2
n < 4 == True, n: 2
First print: 3
n < 4 == True, n: 3
First print: 4
n < 4 == False, n: 4
Second print: 4
Second print: 3
Second print: 2
Second print: 1
0

because of the location of print(n), it happens after the for if statement. Also, since it is part of that function, it will print every time the function is called. But since you have called that function four times, it will hit that print statement 4 times. I thank the reason it prints and descending order is that Each time you call the method it’s added to the stack of th global execution context. It’s easiest to understand the stack with a simple diagram which can be found on there the recursive functions section in this document. The stack follows last in 1st out rule, Thus, when the four methods pop off the stack your print will start with the latest definition and continue popping things off the stack in reverse order.

Not the answer you're looking for? Browse other questions tagged or ask your own question.