4

我不明白,我怎样才能返回 aList而不是 a None

class foo():
    def recursion(aList):
        if isGoal(aList[-1]):
            return aList
        for item in anotherList:
            newList = list(aList)
            newList.append(item)
            recursion(newList)

    someList = [0]
    return recursion(someList)

基本上代码是记录所有路径(从 0 开始)。谁先得到 100 将被退回。isGoal()是检查路径的最后一项是否为 100。并且anotherList是一个随机数的小列表(从 0 到 100)。

4

2 回答 2

16

return陈述

当我第一次开始学习递归时,这个问题实际上花了我很长时间才掌握。

在处理 Python 函数/方法时要记住的一件事是,无论如何它们总是一个值。 return所以假设你忘记return在你的函数/方法的主体中声明一个语句,Python 会为你处理它并return None在它的最后做。

这意味着,如果您在函数体中搞砸并放错了return或省略了它,而不是预期的返回,您print type(messed_up_function())将打印NoneType

递归修复

现在考虑到这一点,在处理递归时,首先要确保除了归纳案例之外还有一个基本案例,即防止无限递归循环。

接下来,确保你在两种情况下都返回,所以像这样:

def recur(val):
    """
    takes a string
    returns it back-to-front
    """
    assert type(val) == str
    # the base case
    if len(val) == 1:
        return val
    # the inductive case
    else:
        return val[-1] + recur(val[:-1]) # reverses a string char by char

所以它的作用是它总是returns 并且是 100% 无限递归证明,因为它有一个有效的基本情况,并且在每个归纳步骤中都有一个递减的长度。

Stack Viewer 调试递归函数

recur('big')如果我们在基本情况开始时使用添加的内容运行assert False,我们将具有以下堆栈结构:

范围

从中我们可以看到,在每一个递归步骤中,我们都有val,这是这个函数的唯一参数,它越来越小,直到len(val) == 1它到达,然后它到达最终的返回,或者在这种情况下assert False。所以这只是调试递归函数/方法的一种方便方法。在IDLE中,您可以通过调用Debug > Stack Viewershell 来访问这样的视图。

于 2013-03-11T14:10:26.517 回答
0

功能是这样的:

def recursion(aList):
    if isGoal(aList[-1]):
        return aList
    for item in anotherList():
        newList = list(aList)
        newList.append(item)
        recursion(newList) # here you ignore what recursion returns
    # when execution reaches this point, nothing is returned

如果执行到达我添加的注释,则在 for 循环完成后,函数退出并且不返回任何内容。并且当您在没有执行return语句的情况下退出函数时,None返回。您必须确保从递归函数返回某些内容。

我无法就如何重写该函数向您提供建议,因为我不知道它要做什么。对我来说,它需要如何改变远非显而易见。但是,我可以完全自信地说,你必须回报一些东西!

于 2013-03-11T13:50:57.007 回答