【问题标题】:Function always returns None [duplicate]函数总是返回 None [重复]
【发布时间】:2013-04-03 13:40:19
【问题描述】:

我有一些基本上看起来像这样的 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("abc") 替换正常的return 语句,它仍然是None

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

【问题讨论】:

  • 递归调用时使用return process(my_list)
  • @NPE 我假设#do some stuff 包括以某种方式修改列表;否则你是对的;这应该无限期地递归。
  • do some stuff 确实修改了列表,所以不应该发生无限递归。但丢失的回报确实是问题所在,我不知道必须这样做。
  • 这能回答你的问题吗? Why does my recursive function return None?

标签: python return


【解决方案1】:

发生了什么:

  1. 你打电话给process(my_start_list)
  2. 在函数中,如果len(my_list) > 1,则执行if块,并且那里没有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

【讨论】:

    【解决方案2】:

    只有当列表中有 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
    

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

    【讨论】:

    • 他的函数是递归的;无论他做什么,他最终都会得到至少两个 return 语句(一个用于基本情况,一个用于递归调用)。
    • @marksweb:为什么单个回报会更好?这已经被讨论到死了,但这不再是真的。见Should a function have only one return statement?
    • @MartijnPieters 鉴于我的经验,我愿意犯错,但这是我一直被告知的以及我如何工作以使跟踪事情变得更容易。我会阅读那篇文章!
    【解决方案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) > 1True 时,您实际上传递了递归调用的返回值。

    【讨论】:

      【解决方案4】:

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

      我个人会将尾递归转化为迭代:

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

      我认为这让意图更清晰一些,也避免了一些pitfalls associated with tail recursion

      【讨论】:

        猜你喜欢
        • 2020-06-14
        • 1970-01-01
        • 2023-01-12
        • 1970-01-01
        • 2021-02-18
        • 2022-11-21
        • 2014-08-28
        • 1970-01-01
        相关资源
        最近更新 更多