11

我有一些基本上看起来像这样的 Python 代码:

my_start_list = ...

def process ( my_list ):
    #do some stuff
    
    if len(my_list) > 1:
        process(my_list)
    else:
        print(my_list)
        return my_list
   
print(process(my_start_list))

奇怪的是:print(my_list)打印出正确的内容。但是,打印函数返回值的第二条打印语句总是打印None. 即使我return用它替换正常的语句return("abc")仍然是None.

由于变量的内容在 return 语句前一行似乎是正确的,我不知道从哪里开始调试。是否有任何常见问题可能导致此问题?

4

4 回答 4

17

这是发生的事情:

  1. 你打电话process(my_start_list)
  2. 在函数中,该if块被执行 if len(my_list) > 1,并且那里没有 return 语句。现在,由于else尚未执行,并且因为这是您拥有 return 子句的唯一地方,所以您返回默认值,即None.
  3. 如果列表中有 0 或 1 个元素,则返回该列表。

要解决此问题,您需要返回由process(my_list).

那是:

def process(my_list):
    # do some stuff
    ...
    if len(my_list) > 1:
        return process(my_list)
    else:
        print(my_list)
        return my_list
于 2013-04-03T13:50:13.770 回答
9

只有当列表中有 1 或 0 个元素时(基本情况),您才会返回列表。您还需要在第一个块中使用 return 语句,在其中进行递归调用,或者深入到基本情况,将长度为 1 的列表返回到下一个级别,然后返回None其余部分。所以你想要的看起来像这样,而不是:

def process(my_list):
    # Do some stuff.
    if len(my_list) > 1:
        return process(my_list) #If you don't return this result, you return None
    else:
        print(my_list)
        return my_list

现在每个案例(不仅仅是基本案例)都有一个返回值,因此该返回值将一直传播到您的初始调用。

于 2013-04-03T13:42:29.783 回答
3

process递归地调用,但当你这样做时永远不要忽略它的返回值。添加一个return语句来传递返回值::

def process ( my_list ):
    #do some stuff

    if len(my_list) > 1:
        return process(my_list)
    else:
        print(my_list)
        return my_list

现在,当len(my_list) > 1is时True,您实际上传递了递归调用的返回值。

于 2013-04-03T13:43:33.973 回答
2

正如其他人指出的那样,您缺少一个return声明。

我个人会将尾递归变成迭代:

def process(my_list):
    while True:
        # do some stuff
        if len(my_list) <= 1:
            return my_list

我认为这使意图更加清晰,并且还避免了与尾递归相关的一些陷阱

于 2013-04-03T13:58:35.467 回答