2
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?

3
  • 2
    Do you understand that print(1);print("bob");print(1); prints 1 twice? Commented Sep 2, 2022 at 22:26
  • 3
    It isn’t reducing… it is showing the value of a as it steps out of the recursion. Recursion stops when you reach a = 10 because of the if a < 10:, then your second print runs for the current iteration, then it can run for the previous iteration and so on. Commented Sep 2, 2022 at 22:29
  • The short answer is that you print(a) twice, so you will see every value of a printed twice. Commented Sep 2, 2022 at 23:36

1 Answer 1

3

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:
*
**
***
****
*****
*****
****
***
**
*
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.