How to rewrite this function as a recursive function?

时光毁灭记忆、已成空白 提交于 2019-12-25 04:05:12

问题


def digits(n):
    res = []
    while n > 0:
        res.append(n % 10)
        n /= 10
    return res

I want to rewrite this function so it uses recursion. I'm currently lost as to what to do. Can anyone give me some direction?


回答1:


Here's a possible solution:

def digits(n):
    if n < 10:
        return [n]
    return digits(n/10) + [n%10]

digits(123)
> [1, 2, 3]

The above solution fixes a bug in your code, you were returning the digits in reverse order. Also notice that n must be an integer greater than or equal to zero for producing correct results.

Here's how it works:

  1. If the number is less than 10, then return a list with the number, as there are no more digits to be processed
  2. If the number is greater than 9, get the last digit in the current number and add it to the end of the list that results of recursively calling digits on a smaller number - namely, the number without the last digit that we just processed.

The call to digits(123) will look like this at each step of the recursion:

digits(123) = digits(123/10) + [3]
digits(12)  = digits(12/10)  + [2]
digits(1)   = [1]

Now we go up the call stack:

[1]
[1] + [2]
[1, 2] + [3]
[1, 2, 3]

EDIT :

Accepting @thg435's challenge, here's a tail-recursive solution:

def digits(n):
    def loop(i, acc):
        if i < 10:
            return [i] + acc
        return loop(i/10, [i%10] + acc)
    return loop(n, [])



回答2:


To create a recursive function you need to determine two things:

1) The base case - the condition on which you want to stop recursion

2) The general case - what to do on every input but the base case

You have already found both of these things, the base case is the while loop condition and the general case is the inside of the while loop. Try to use this information to move forward.




回答3:


When you use recursion, a good basis is to have two cases to check, a base case and a recursive case. The base case is the conditions and result under which the program returns, in your case, the base case would be when n > 0 (If you think of it like a while loop, it's the condition for the while loop exiting). The recursive case (there can be multiple of these) occur when the loop isn't done, if you compare to a while loop, this is basically the body of the loop. At the end of the recursive case, you need to call the function again with your changes to the input, in this case n/10.

So, your function definition would be something like:

def digits(n):

For the base case, you want to check if n is 0, and, if it is, return the empty list:

    if n <= 0:
        return []

Now, in the recursive case, you want to append n%10 to the list and call your function again, only you want to call it with a different n, changed as you had it in your while loop:

    else:
        return [n%10]+digits(n/10)

So, if you trace this through, for every recursive case, you get a list containing n%10, then it adds the result of the new call, which will be either (n/10)%10 or the empty list. For example, running this function with n=100 would break down like this:

newlist = digits(100)
newlist = [100%10]+digits(100/10)
newlist = [100%10]+([10%10] + digits(10/10))
newlist = [100%10]+([10%10] + ([1%10] + digits(10/10)))
newlist = [100%10]+([10%10] + ([1%10] + ([])))
newlist = [0,0,1]

Nested parens are used to show how the function digits gets rewritten inline.




回答4:


def digits(n):
    res = []
    res.append(n%10)
    n /= 10
    if n != 0:
        return res + digits(n)
    else:
        return res


来源:https://stackoverflow.com/questions/10568848/how-to-rewrite-this-function-as-a-recursive-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!