在python中创建递归函数

时间:2013-06-17 11:24:11

标签: python recursion

这是一个家庭作业问题。我尝试获得一个递归函数:

def problem_a(n):
    answer.append(n)
    if n == 1:
        return answer    
    elif n % 2 == 0:
        answer.append(n/2)
    else :
        answer.append(n*3 + 1)
        problem_a(n*3 + 1)

此代码显然不起作用,因为answer未定义为列表。使用循环它可以工作,但我想做一个递归函数。我可以使用列表作为输入,但我想知道是否存在更优雅的东西。

problem_a(7)应该作为输出:

[7, 22, 11, 34, 17, 52, 26, 13, 40 , 20, 10 ,5 ,16, 8, 4, 2, 1]

5 个答案:

答案 0 :(得分:2)

您可以定义局部变量answer并在递归调用中传递它。

def problem_a(n, answer = None):
    answer = [n] if answer is None else answer
    if n == 1:
        return answer
    elif n % 2 == 0:
        n = n/2
        answer.append(n)
    else:
        n = n*3 + 1
        answer.append(n)
    return problem_a(n, answer)

print problem_a(7)        

<强>输出:

[7, 22, 11, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1]

答案 1 :(得分:2)

你可以尝试一下发电机:

def problem_a(n):
    yield n
    if n == 1:
        return
    elif n % 2 == 0:
        x = n / 2
    else:
        x = n * 3 + 1

    for y in problem_a(x):
        yield y

print list(problem_a(7))

答案 2 :(得分:2)

到目前为止已经建议的一种替代解决方案(使用额外的参数将列表递送到递归链)是在从递归返回时构建最终列表。这不是非常有效,因为连接列表需要复制它们,但它可以工作:

def problem_a(n):
    if n == 1:
        return [n]
    elif n % 2 == 0:
        return [n] + problem_a(n // 2)
    else:
        return [n] + problem_a(3*n + 1)

答案 3 :(得分:1)

您的骨架解决方案存在问题。您需要在n % 2 == 0以及最终else时递归。 answer变量被赋予一个默认值,以便在首次调用函数时没有参数将其初始化为[]

def problem_a(n, answer=None):
    if answer == None:
        answer = []

    answer.append(n)
    if n == 1:
        return answer    
    elif n % 2 == 0:
        return problem_a(n/2, answer)
    else :
        return problem_a(n*3 + 1, answer)

>>> problem_a(7)
[7, 22, 11, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1]

修改

根据评论,使用可变的默认参数是个坏主意。只需将其设置为无,就像在其他帖子中一样,并检查其是否为无以创建新列表。我改变了答案以反映这一点。

原始的错误代码如下:

def problem_a(n, answer=[]):
    answer.append(n)
    ...

答案 4 :(得分:1)

您也可以使用闭包:

>>> def s():
    ret = []
    def f(n):
        ret.append(n)
        if n % 2 == 0:
            f(int(n/2))
        elif n != 1:
            f(int(n*3 + 1))
        return ret
    return f

>>> s()
<function f at 0x00000000033A5848>
>>> s()(7)
[7, 22, 11, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1]