not able to understand the output of a recursion program in python

Question:

def add(a):
    a = a + 1
    print(a)
    if a < 10:
        add(a)
    print(a)
add(1)

here is the executed code

I don’t understand why the value of a started reducing after 10 when it should’ve stopped at 10 even without an else statement. Can anyone explain the reason?

Asked By: hackerbat

||

Answers:

print() debugging

def add(a):
    a = a + 1
    print(f"#1, a: {a}, id: {id(a)}")
    if a < 10:
        add(a)
    print(f"#2, a: {a}, id: {id(a)}")

add(1)

# stdout:
#1, a: 2, id: 9801280
#1, a: 3, id: 9801312
#1, a: 4, id: 9801344
#1, a: 5, id: 9801376
#1, a: 6, id: 9801408
#1, a: 7, id: 9801440
#1, a: 8, id: 9801472
#1, a: 9, id: 9801504
#1, a: 10, id: 9801536
#2, a: 10, id: 9801536
#2, a: 9, id: 9801504
#2, a: 8, id: 9801472
#2, a: 7, id: 9801440
#2, a: 6, id: 9801408
#2, a: 5, id: 9801376
#2, a: 4, id: 9801344
#2, a: 3, id: 9801312
#2, a: 2, id: 9801280

And if you disassemble:

import dis
    
dis.dis(add)

The bytecode doesn’t show any BINARY_SUBTRACT operation.

Explanation

  1. The if statement recursively executes add() until the last line of the function, which then "waits" for the older add() calls to end.

  2. Each n call was called by the n-1 one, as it is shown on the stdout: this results in all these waiting stacked calls being executed in a LIFO order.

  3. At the end, a‘s value is not being decremented, instead is printed with the old values from each previous stacked call, in a "chiastic" fashion.

Extra

This kind of recursion can be used for printing pyramids (double top) on the stdout:

def print_pyramid(a):
    a = a + 1
    print(a*'*')
    if a < 5:
        print_pyramid(a)
    print(a*'*')
    
print_pyramid(0)

# stdout:
*
**
***
****
*****
*****
****
***
**
*
Answered By: Jonathan Ciapetti
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.