def func(my_list, z):

    if z == len(my_list):
        return something
    else:
        # do something else
        return func(my_list, z+1)

z = someValue
print func(my_list, z)    

You should not use list as variable name.

Answer from Rohit Jain on Stack Overflow
Top answer
1 of 2
49

Actually you should break the function down first:

A loop has a few parts:

  1. the header, and processing before the loop. May declare some new variables

  2. the condition, when to stop the loop.

  3. the actual loop body. It changes some of the header's variables and/or the parameters passed in.

  4. the tail; what happens after the loop and return result.

Or to write it out:

foo_iterative(params){
    header
    while(condition){
        loop_body
    }
    return tail
}

Using these blocks to make a recursive call is pretty straightforward:

foo_recursive(params){
    header
    return foo_recursion(params, header_vars)
}

foo_recursion(params, header_vars){
    if(!condition){
        return tail
    }

    loop_body
    return foo_recursion(params, modified_header_vars)
}

Et voilร ; a tail recursive version of any loop. breaks and continues in the loop body will still have to be replaced with return tail and return foo_recursion(params, modified_header_vars) as needed but that is simple enough.


Going the other way is more complicated; in part because there can be multiple recursive calls. This means that each time we pop a stack frame there can be multiple places where we need to continue. Also there may be variables that we need to save across the recursive call and the original parameters of the call.

We can use a switch to work around that:

bar_recurse(params){
    if(baseCase){
        finalize
        return
    }
    body1
    bar_recurse(mod_params)
    body2
    bar_recurse(mod_params)
    body3
}


bar_iterative(params){
    stack.push({init, params})

    while(!stack.empty){
        stackFrame = stack.pop()

        switch(stackFrame.resumPoint){
        case init:
            if(baseCase){
                finalize
                break;
            }
            body1
            stack.push({resum1, params, variables})
            stack.push({init, modified_params})
            break;
        case resum1:
            body2
            stack.push({resum2, params, variables})
            stack.push({init, modified_params})
            break;
        case resum2:
            body3
            break;
        }
    }
}
2 of 2
2

Following up on @ratchet freak's answer, I created this example of how the Fibonacci function can be rewritten to a while loop in Java. Note that There's a much simpler (and efficient) way to rewrite the Fibonacci with a while loop though.

class CallContext { //this class is similar to the stack frame

    Object[] args;

    List<Object> vars = new LinkedList<>();

    int resumePoint = 0;

    public CallContext(Object[] args) {
        this.args = args;
    }

}


static int fibonacci(int fibNumber) {
    Deque<CallContext> callStack = new LinkedList<>();
    callStack.add(new CallContext(new Object[]{fibNumber}));
    Object lastReturn = null; //value of last object returned (when stack frame was dropped)
    while (!callStack.isEmpty()) {
        CallContext callContext = callStack.peekLast();
        Object[] args = callContext.args;
        //actual logic starts here
        int arg = (int) args[0];
        if (arg == 0 || arg == 1) {
            lastReturn = arg;
            callStack.removeLast();
        } else {
            switch (callContext.resumePoint) {
                case 0: //calculate fib(n-1)
                    callStack.add(new CallContext(new Object[]{arg - 1}));
                    callContext.resumePoint++;
                    break;
                case 1: //calculate fib(n-2)
                    callContext.vars.add(lastReturn); //fib1
                    callStack.add(new CallContext(new Object[]{arg - 2}));
                    callContext.resumePoint++;
                    break;
                case 2: // fib(n-1) + fib(n-2)
                    callContext.vars.add(lastReturn); //fib2
                    lastReturn = (int) callContext.vars.get(0) + (int) callContext.vars.get(1);
                    callStack.removeLast();
                    break;
            }
        }
    }
    return (int) lastReturn;
}
Discussions

algorithm - Convert python while loop to recursion - Stack Overflow
Herbert attempts to climb the slope (Heffalumps are heavy), so each of his rushes gains him only 95% as much distance as his previous rush. This means that if his first rush gains him rush_height_g... More on stackoverflow.com
๐ŸŒ stackoverflow.com
python - Convert recursive function into a for loop and while loop - Stack Overflow
I need to convert def aRecursive(n): if n is 1: return 3 else: return 2 * aRecursive(n-1) + 5 into a for loop and a while loop. I can't seem to wrap my mind around the proc... More on stackoverflow.com
๐ŸŒ stackoverflow.com
October 4, 2017
python - When to use while loops vs recursion - Stack Overflow
I am a beginner and I am beginning to learn about 'while' statement loops to perform iteration. However, earlier on I learned about 'if/else' statements and how one can perform recursion using if/e... More on stackoverflow.com
๐ŸŒ stackoverflow.com
python - Convert for loop to recursive function in python3 - Stack Overflow
Is it possible to convert the following loop: c = 0 for a in find: c += 1 return c Where find is a list like [a,b,c,d] to a function that uses recursion without using external libraries? More on stackoverflow.com
๐ŸŒ stackoverflow.com
๐ŸŒ
Refactoring
refactoring.com โ€บ catalog โ€บ replaceIterationWithRecursion.html
Replace Iteration with Recursion - Refactoring
The implementation of the function should be an 'if' statement, which tests the looping condition (the condition expression in "while (condition) ...;"). The "then" clause should calculate/return the final result. The "else" clause should make the recursive call, with appropriately modified ...
๐ŸŒ
Quora
quora.com โ€บ Can-we-use-while-loops-to-implement-recursion-in-Python
Can we use while loops to implement recursion in Python? - Quora
Answer (1 of 2): Yes but this is true for any recursion. even so besides while loops you are also going to need some kind of data structure to act as the stack, if your original recursion has more than 1 branch
Top answer
1 of 2
4

I am going to offer a solution based on how functions are called. This solution is generic, in that you can use the same approach to convert any recursive function to an iterative one. It is theoretically possible but it seems no one talks about how. Since your function is easy, it is not hard to come up with a iterative one. But how about non-recursive post-order traversal of a binary tree? You can only do it on a case by case basis if you don't have a generic approach that I am going to present.

Here we go. First we need to write down your recursive version with a slight change to facilitate the conversion:

def f(N):
    n = N        # N is the top level parameter passed to this function
    res = None   # res is the result returned by this function
[start]:         # here we create a label; not python, only for converting
    if n == 1:
        return 3
    else:
        return 2 * f(n-1) + 5

Next we are going to convert two things: the function call and the return statements. The function call is basically 2 steps: push parameters and return address to stack and jump to the actual code. The return is basically pop parameters and jump to the saved address. So here we go:

def f(N):
    n = N        # N is the top level parameter passed to this function
    res = None   # res is the result returned by this function
[start]:         # here we create a label; not python, only for converting
    if n == 1:
        return 3
    else:
        push(n)       # push current parameter; since there is only one recursive function call in the body, we know where to return and there is no need to push the return address
        n = n-1       # the next level actual parameter is now n-1
        goto [start]  # we go to the code of the function which is the start of this same function
        return 2 * f(n-1) + 5  # we will never reach here... this line is where we need to return when any `return` statements is met

Next we will change the first return statements (the return 3):

def f(N):
    n = N        # N is the top level parameter passed to this function
    res = None   # res is the result returned by this function
[start]:         # here we create a label; not python, only for converting
    if n == 1:
        res = 3
        # for `return` we need to see if this is the top level or a inner recursive call
        if stack is empty: # we are in top level
            return res
        # hey we are in a recursive call, and we need to return to the code after `goto`, why not move these code here?
        else:
            n = pop()      # we pop the parameter saved
            # this line is where we need to return when any `return` statements is met
            return 2 * f(n-1) + 5
    else:
        push(n)       # push current parameter; since there is only one recursive function call in the body, we know where to return and there is no need to push the return address
        n = n-1       # the next level actual parameter is now n-1
        goto [start]  # we go to the code of the function which is the start of this same function

Then we will convert the return 2*f(n-1)+5:

def f(N):
    n = N        # N is the top level parameter passed to this function
    res = None   # res is the result returned by this function
[start]:         # here we create a label; not python, only for converting
    if n == 1:
        res = 3
        if stack is empty:
            return res
        else:
            [loop]:
            n = pop()      # we pop the parameter saved
            # begin conversion of return
            res = 2*res+5
            if stack is empty:
                return res;
            else:
                # we need to pop stack and jump to the same return, so we just jump to [loop]
                goto [loop]
    else:
        push(n)       # push current parameter; since there is only one recursive function call in the body, we know where to return and there is no need to push the return address
        n = n-1       # the next level actual parameter is now n-1
        goto [start]  # we go to the code of the function which is the start of this same function

Now the conversion is done, and we need to simplify this mess. First we should consider if a stack is really need. For this particular problem, every push just make n=n-1 and every pop makes n=n+1. So the stack is not really needed.

def f(N):
    n = N        # N is the top level parameter passed to this function
    res = None   # res is the result returned by this function
[start]:         # here we create a label; not python, only for converting
    if n == 1:
        res = 3
        if n == N:         # SAME as stack is empty
            return res     # really return
        else:
            [loop]:
            n = n+1       # WE JUST INCREASE N INSTEAD OF POP
            res = 2*res+5
            if n==N:      # SAME as stack is empty
                return res;
            else:
                goto [loop]
    else:
        # NO PUSH NEEDED
        n = n-1       # the next level actual parameter is now n-1
        goto [start]

The stack is eliminated, and we need to make these goto statements disappear. Notice the [start] label and goto [start] makes a loop, we just need to make them a 'while' loop:

def f(N):
    n = N        # N is the top level parameter passed to this function
    res = None   # res is the result returned by this function
    # we reverse the if n==1 and make it a condition in while
    while n != 1:
        # NO PUSH NEEDED
        n = n-1       # the next level actual parameter is now n-1
    # you soon noticed the above calculation is not needed at all, it just sets n = 1

    res = 3
    if n == N:
        return res
    else:
        [loop]:
        n = n+1
        res = 2*res+5
        if n==N:
            return res;
        else:
            goto [loop]

We optimized the first loop and replace them with n=1. And we need to make the second loop labeled by [loop] and goto [loop] disappear:

def f(N):
    n = N        # N is the top level parameter passed to this function
    res = None   # res is the result returned by this function
    n = 1        # the result of the first while loop

    res = 3
    if n == N:
        return res
    else:
        do:              # Python does not have do while, but it is straight forward to do this convert
            n = n+1
            res = 2*res+5
        while n!=N
        return res

We will soon notice that the first 4 statements can be combined and we remove all comments:

def f(N):
    n = 1
    res = 3
    if n == N:
        return res
    else:
        do:
            n = n+1
            res = 2*res+5
        while n!=N
        return res

We will reverse the if n==N statement:

def f(N):
    n = 1
    res = 3
    if n != N:
        do:
            n = n+1
            res = 2*res+5
        while n!=N
        return res
    else:
        return res

It is obvious that return res can be put on top level and the if n!=N and do/while loop can be combined to a single while loop:

def f(N):
    n = 1
    res = 3
    while n != N:
        n = n+1
        res = 2*res+5
    return res

This is the equivalent version of the original recursive function. Notice that I do not dig into this specific problem to come up with this version, I only deal with function call conversions. I suggest you go through the whole process on your own in your favorite text editor and it is kind of fun. You will find it is very mechanical and the only thing that requires some thought is the stack usage. Other techniques like "reverse if conditions" or "convert goto to structural loops" are quite easy.

It is also interesting to see that the iterative version is more efficient than the recursive one based only on the conversion process alone because: 1. we eliminate the use of the stack; 2. we eliminate a loop that decrease n to 1. We at least save some CPU cycles and stack storage.

2 of 2
3

One possible for loop:

def a(n):
    answer = 3

    for i in range(n - 1):
        answer = answer * 2 + 5

    return answer

A possible while loop, though I don't particularly like using a while here:

def a(n):
    answer = 3

    while n > 1:
        answer = answer * 2 + 5
        n -= 1

    return answer

Note that neither of these answers (nor your original code) handle an n less than 1.

Explanation

a(1) = 3
a(n) = 2 * a(n - 1) + 5

So if you were to compute a(5), there are two reasonable approaches. One is to write out something recursive:

a(5) = 2 * a(4) + 5

Then compute a(4):

a(4) = 2 * a(3) + 5

so a(5) is now:

a(5) = 2 * (2 * a(3) + 5) + 5

You can continue this process until you don't have any references to a anymore, and then you can just do arithmetic.

The non-recursive way would be to count up:

a(1) = 3
a(2) = 2 * a(1) + 5  =  2 *  3 + 5  =  11
a(3) = 2 * a(2) + 5  =  2 * 11 + 5  =  27
a(4) = 2 * a(3) + 5  =  2 * 27 + 5  =  59
a(5) = 2 * a(4) + 5  =  2 * 59 + 5  =  123

This way, you start with 3 and then at each step, multiply by 2 and add 5 to obtain the next number. Just stop when you reach the n you were trying to compute the function of.

This second (non-recursive) method is how the for and while loops above work.

๐ŸŒ
YouTube
youtube.com โ€บ watch
How to Write Recursion Instead of For/While Loop - YouTube
Hi everyone! In this video, I will show you how to write a function using recursion instead of for loop or a while loop. In other words, I show you how to co...
Published ย  April 25, 2022
Top answer
1 of 2
1

You are actually right, the logic behind is the same and you can also apply while loop for e.g. Fibonacci sequence. Just the notation of recursion is usually shorter and more elegant.

Your code can be even simplified a bit and then you see that your solutions are kind of similar:

While loop:

Copydef countdown(n):
    while n > 0: # Step 1 -> check
        print(n)
        n = n-1 # Step 2  -> recursive call in while loop
    print('Blast off!') # Step 3 -> end ensured by Step 1

Recursion:

Copydef countdown(n):
    if n > 0: # Step 1 -> check
        print(n)  
        return countdown(n-1) # Step 2 -> recursive call of the countdown()
    else:
        print('Blast off!') # Step 3 -> end ensured by Step 1

Significant is that action n-1. You recursively act on a variable or object (Step 2) as long as your condition related to that variable/object is valid (Step 1).

2 of 2
0

They are fundamentally different. The way you have described them, both are the same thing as for loops. (I don't mean to be rude) While is used when you want something to happen as long as or until something else happens. Recursion is used for functions that are based on themselves. (common examples being factorial or the Fibonacci sequence) Often, they behave similarly in the manner you described on small scale problems. When scaled up however, both have their advantages and drawbacks.

TLDR: the functions are inherently different in how they iterate. While they each iterate, they do so based on different conditions and with different use cases.

Find elsewhere
๐ŸŒ
Wikibooks
en.wikibooks.org โ€บ wiki โ€บ Non-Programmer's_Tutorial_for_Python_3 โ€บ Recursion
Non-Programmer's Tutorial for Python 3/Recursion - Wikibooks, open books for an open world
Though, there are other uses for Recursion that are very valid, where while loops or for loops may not be optimal. Recursion can be controlled, just like loops. Lets look at an example of a controlled loop. # Program by Mitchell Aikens # No copyright # 2012 def main(): loopnum = int(input("How many times would you like to loop?\n")) counter = 1 recurr(loopnum,counter) def recurr(loopnum,counter): if loopnum > 0: print("This is loop iteration",counter) recurr(loopnum - 1,counter + 1) else: print("The loop is complete.") main()
๐ŸŒ
Quora
quora.com โ€บ How-do-you-convert-iterative-code-to-recursive
How to convert iterative code to recursive - Quora
Answer (1 of 5): Here the iterative code to find the factorial of a given number. [code]n=5 res=1 for i in range(n,0,-1): res*=i print(res) [/code]Output: 120 To convert the iterative code to recursive code , first you need to find the terminating condition which end the function call and the...
Top answer
1 of 5
2

how about this ?:

def fibonacci(n, a=0, b=1):
   if a >= n : return [a]
   return [a] + fibonacci(n,b,a+b)

[EDIT] Here's how it works:

The function progressively builds an array by adding one element [a] to the result of the next call to itself.

The first line allows it to stop when the target is reached. Without it, the second line of the function would keep calling itself and there would never be a result coming back from the recursion.

Because the parameters of a function are local to each call, the value of a and b in the second call are different from the previous ones.

If we follow the logic for fibonacci(7), we get:

1) fibonacci(n=7, a=0, b=1) ==> will return [0] + fibonacci(7,1,1).

2) fibonacci(n=7, a=1, b=1) ==> will return [1] + fibonacci(7,1,2).

3) fibonacci(n=7, a=1, b=2) ==> will return [1] + fibonacci(7,2,3).

4) fibonacci(n=7, a=2, b=3) ==> will return [2] + fibonacci(7,3,5).

5) fibonacci(n=7, a=3, b=5) ==> will return [3] + fibonacci(7,5,8).

6) fibonacci(n=7, a=5, b=8) ==> will return [5] + fibonacci(7,8,13).

7) fibonacci(n=7, a=8, b=13) ==> 8 >= 7 so the first line returns [8]

At that point there are no more recursive calls (the first line returns without calling the function again) and the return values start coming back up.

7) returns [8]

6) returns [5,8]

5) returns [3,5,8]

4) returns [2,3,5,8]

3) returns [1,2,3,5,8]

2) returns [1,1,2,3,5,8]

1) returns [0,1,1,2,3,5,8]

One way to think about recursive functions is to look only at the incremental work to be done on the result that would be produced by a prior parameter value. Most of the time this part of the logic applies backwards (i.e computing the end result based on a previous one). For example, a factorial can be thought of as the multiplication of a number with the factorial of the previous number.

This gives you the equivalent of the second line.

Once you have that down, all you need to decide is the condition that makes the recursion stop. Usually this corresponds to the smallest/simplest use case. For example, a factorial does not need to recurse when the number is less than 2 so the function can return 1 directly.

This gives you the equivalent of the first line.

As you can see in the above tracing, the function will proceed "forward" but actually ends up waiting for a result from itself (with different parameters) before being able to complete the process. This is how recursive functions work. The final result is typically built when the return values come back up from the stack of multiple self-calls.

Your fibonacci function is a bit trickier than a factorial because the series can only be computed from the original (0,1) values. Unlike the factorial, we don't have enough information to figure out the value of a and b based on the supplied parameter (n).

And, if you'd like to sink you teeth in cryptic code, here's a one line version:

def fibo(n,a=0,b=1):return [a]+fibo(n,b,a+b) if a < n else [a]
2 of 5
1

The point of a recursive implementation is to organize things like this:

if we're at a base case:
    return the result for that base case
else:
    call ourselves with a reduced case
    possibly modify the result
    return the result

For the base case, a < n, what you do should be related to what you do after the while loop in the iterative version. Adding the last value to the accumulator list fib and returning it makes sense. It may or may not be right, but it's at least in the right direction.

But in your recursive case, you're not calling yourself with a reduced case, you're just calling yourself with the exact same arguments. That's obviously going to be an infinite loop. (Well, Python doesn't do tail call elimination, so it's going to be a stack overflow, which shows up as a max recursion exception, but that's no better.)

So, what should you be doing? Something related to what happens inside the original non-recursive while loop. What you were doing there is:

fibonacci.append(b)
a, b = b, a+b

So, the equivalent is:

fib.append(b)
return fibo(n, b, a+b, fib)

Again, that may not be right, but it's in the right direction. So, if you get the idea, you should be able to carry on from there to debugging the full function.

๐ŸŒ
Quora
quora.com โ€บ How-would-you-convert-a-recursion-into-a-for-loop
How would you convert a recursion into a for loop? - Quora
When recursion is simple (tail recursion or fixed small-depth recursion) you can use a for/while loop; for general recursion (tree/graph traversal, divide-and-conquer) use an explicit stack or queue.
๐ŸŒ
Reddit
reddit.com โ€บ r/learnpython โ€บ loops vs recursion
r/learnpython on Reddit: Loops vs recursion
April 30, 2018 -

So I was watching this video on youtube and was simply amazed by this function to calculate factorials with recursions.

def factorials(n):
    if n == 1:
        return 1
    else:
        return n * factorial(n-1)

Since I'm pretty new to python and coding in general (I'm a lawyer by profession), I would have solved this problem with loops. The moment I understood the concept of this function, I was baffled by the simplicity and beauty of it.

Now here's my question:

  1. In which cases is it smarter to use one or the other and what are the benefits? (if there even is a general rule)

  2. Where can I learn more about recursions? Are there any tutorials online?

Thanks :)

Top answer
1 of 5
36
Every recursive solution can be expressed as a loop, and vice versa. In Python, you use recursion when the recursive solution makes it easier to understand (you would probably use a loop for a factorial) Recursions are heavily used in functional programming (which Python does not excel at), and Guido said he prefers loops instead of recursion. If you like recursion and mathematical elegance in programming, I recommend you take a look at functional programming and functional programming languages. Be advised though that functional programming can be difficult to grasp at first.
2 of 5
20
You CAN solve almost any problem using almost any loop. But when is it more appropriate to use which loop, my opinion is this: A while loop is the correct solution when the data amount and endpoint is unknown. A for loop is the correct solution when the amount of data, and endpoint is known. A Recursion is the correct solution when the amount is known, but the end point is not. So what I mean by that is, imagine finding a file in a bunch of folders. Inside every folder the AMOUNT of files are known, so you use a for loop to walk through the files and you pick out the right file. But how many folders do you need to go through? You don't know that, because every subfolder COULD have another subfolder, or not. And so the folder structure branches out, in an unknown way. This becomes difficult to deal with using multiple for loops. Again, because the endpoint is unknown. Here recursion is the perfect solution. find_file(folder): global filelist for file in folder.files: if ".jpg" in file.name: filelist.append(file) for subfolder in folder.dirs: find_file(subfolder)
๐ŸŒ
Wordpress
argandgahandapandpa.wordpress.com โ€บ 2008 โ€บ 03 โ€บ 27 โ€บ turning-a-while-loop-into-a-recursive-function
Turning a while loop into a recursive function | Arg and gah and ap and pa
May 5, 2011 - def loop_func(state, constants): if condition(state): return loop_func(f(state, constants), constants) else: return state state = loop_func(init_state, init_constants) ... def f(state): if end_state(state): return f_known(state) new_state = ...
Top answer
1 of 8
213

Recursion is not intrinsically better or worse than loops - each has advantages and disadvantages, and those even depend on the programming language (and implementation).

Technically, iterative loops fit typical computer systems better at the hardware level: at the machine code level, a loop is just a test and a conditional jump, whereas recursion (implemented naively) involves pushing a stack frame, jumping, returning, and popping back from the stack. OTOH, many cases of recursion (especially those that are trivially equivalent to iterative loops) can be written so that the stack push / pop can be avoided; this is possible when the recursive function call is the last thing that happens in the function body before returning, and it's commonly known as a tail call optimization (or tail recursion optimization). A properly tail-call-optimized recursive function is mostly equivalent to an iterative loop at the machine code level.

Another consideration is that iterative loops require destructive state updates, which makes them incompatible with pure (side-effect free) language semantics. This is the reason why pure languages like Haskell do not have loop constructs at all, and many other functional-programming languages either lack them completely or avoid them as much as possible.

The reason why these questions appear so much in interviews, though, is because in order to answer them, you need a thorough understanding of many vital programming concepts - variables, function calls, scope, and of course loops and recursion -, and you have to bring the mental flexibility to the table that allows you to approach a problem from two radically different angles, and move between different manifestations of the same concept.

Experience and research suggest that there is a line between people who have the ability to understand variables, pointers, and recursion, and those who don't. Almost everything else in programming, including frameworks, APIs, programming languages and their edge cases, can be acquired through studying and experience, but if you are unable to develop an intuition for these three core concepts, you are unfit to be a programmer. Translating a simple iterative loop into a recursive version is about the quickest possible way of filtering out the non-programmers - even a rather inexperienced programmer can usually do it in 15 minutes, and it's a very language-agnostic problem, so the candidate can pick a language of their choice instead of stumbling over idiosyncracies.

If you get a question like this in an interview, that's a good sign: it means the prospective employer is looking for people who can program, not people who have memorized a programming tool's manual.

2 of 8
38

It depends.

  • Some problems are very amenable to recursive solutions e.g. quicksort
  • Some languages don't really support recursion e.g. early FORTRANs
  • Some languages assume recursion as a primary means for looping e.g. Haskell

It's also worth noting that support for tail recursion makes tail recursive and iterative loops equivalent, that is, recursion doesn't always have to waste the stack.

Also, a recursive algorithm can always be implemented iteratively by using an explicit stack.

Finally, I'd note that a five-line solution is probably always better than a 100 line one (assuming they are actually equivalent).

๐ŸŒ
Quora
quora.com โ€บ How-do-we-convert-a-while-loop-into-a-recursive-function
How do we convert a while loop into a recursive function? - Quora
Answer: There are a couple of ways of doing this. 1. A loop generally operates over a data structure of some kind. These structures have a public interface. The public interface will often have a fold method exported. Use that instead of a while loop. The fold method in a functional language wil...
๐ŸŒ
Educative
educative.io โ€บ answers โ€บ what-is-the-difference-between-loops-and-recursion-in-python
What is the difference between loops and recursion in Python?
In this function, we use a while loop to calculate the factorial of a number. The function can look a little overwhelming, but with recursion, we can save lines and readability by breaking down the problem.