Search code examples
pythonrecursion

How does the print function know what to print or ignore in a string reversal recursive function?


Here is the code for reversing a string. I understand how this recursive function works (see attached photo). screenshot of the breakdown of code, with the part in question encircled in green

def rev(s):
    if len(s) == 1:
        return s
    if len(s) > 1:
        return rev(s[-1]) + rev(s[:-1])

The output of print(rev("cabin")) is "nibac".

However, the part where I am confused is how does the print function know which returned value to print? Why are the values inside the green circle not being printed? See the green circle in sreenshot.

What I expected to happen is to reverse a string fed into the rev function. What I don't understand is how come only the values of rev[-1] are being printed and not the values of rev[:-1]?


Solution

  • Here's some help to visualize how the recursive function works.

    TLDR is: only the return of the first time you call rev() is returned to the print function, all the other returns end up in the parent rev() that called because len(s) > 1:

    def rev(s, depth=0):
        if len(s) == 1:
            print("│ " * depth + "├─ rev(\"" + s + "\")")
            return s
        if len(s) > 1:
            first_char = s[0]
            rest_of_string = s[1:]
            print("│ " * depth + "├─ rev(\"" + s + "\")")
            print("│ " * (depth + 1) + "├─ rev(\"" + first_char + "\") + rev(\"" + rest_of_string + "\")")
            result = rev(rest_of_string, depth + 2) + rev(first_char, depth + 2)
            print("│ " * depth + "└─ \"" + result + "\"")
            return result
    
    print(rev("cabin"))
    
    

    Output

    print(rev("cabin"))
    ├─ rev("cabin")
    │ ├─ rev("c") + rev("abin")
    │ │ ├─ rev("abin")
    │ │ │ ├─ rev("a") + rev("bin")
    │ │ │ │ ├─ rev("bin")
    │ │ │ │ │ ├─ rev("b") + rev("in")
    │ │ │ │ │ │ ├─ rev("in")
    │ │ │ │ │ │ │ ├─ rev("i") + rev("n")
    │ │ │ │ │ │ │ │ ├─ rev("n")
    │ │ │ │ │ │ │ │ ├─ rev("i")
    │ │ │ │ │ │ └─ "ni"
    │ │ │ │ │ │ ├─ rev("b")
    │ │ │ │ └─ "nib"
    │ │ │ │ ├─ rev("a")
    │ │ └─ "niba"
    │ │ ├─ rev("c")
    └─ "nibac"
    nibac