试图理解递归 - 为什么我的函数达到最大递归或 None?

Trying to understand recursion - Why is my function reaching maximum recursion or None?

这个问题已经被问了很多次,但在浏览了帖子并按照答案所说的内容后,我不明白为什么我的代码仍然无法正常工作

所有关于递归的帖子都说你需要包含一个 return 语句来实际 return 值,而不是 None。但是当我这样做时,我得到了无限递归。我有我的基本案例,以及 collat​​z 序列的其他 2 个案例。我想让它打印出数字,但这是一个无限递归。

#Maximum recursion
def find_collatz_nums(number):
    if number == 1:
        return find_collatz_nums(number)
    if number % 2 == 0:
        return find_collatz_nums(number/2)
    return find_collatz_nums((3 * number) + 1)

print(find_collatz_nums(3))

因此,如果我只是尝试在基本情况下做一个空白 return,它只会 return None。这是下面。

#returns None
def find_collatz_nums(number):
    if number == 1:
        return  #will just return None. 
    if number % 2 == 0:
        return find_collatz_nums(number/2)
    return find_collatz_nums((3 * number) + 1)

print(find_collatz_nums(3))

为什么在第一个代码片段中 return 语句会导致无限递归?

我只是发现自己很困惑,因为这里有大量关于递归的帖子和答案说“你需要 return 语句”,但我已经添加了它们,但代码不起作用。

你所有的分支都是递归的 - 即它们都再次调用该函数。所以,你实际上没有一个基本案例。基本情况是您实际可以直接计算或 return 一个值的情况,而不是递归计算一个值。

考虑另一个可以用递归解决的问题:求列表中数字的总和:

基本情况是当列表为空时,由于没有值,总和仅为 0。

要考虑递归情况,您可以对列表进行切片: 第一项是单个数字,列表的其余部分只是另一个列表。这种情况的总和就是第一项加上列表其余部分的总和:

>>> def find_sum(values):
...     if len(values) == 0:
...             return 0
...     else:
...             return values[0] + find_sum(values[1:])
... 
>>> find_sum([1, 2, 3])
6
>>>

我不知道 Collat​​z 序列是什么,所以我会留给其他人评论递归应该如何寻找它。

如果您遵循您的程序逻辑,这就是函数调用的顺序:

find_collatz_nums (3) -> 
find_collatz_nums (10) -> 
find_collatz_nums (5) ->
find_collatz_nums (16) -> 
find_collatz_nums (8) -> 
find_collatz_nums (4) -> 
find_collatz_nums (2) -> 
find_collatz_nums (1) -> find_collatz_nums (1) -> find_collatz_nums (1).... &  so on

所以你看 python 没有办法停止这个调用 & 它被一次又一次地调用。 这就是为什么你需要一个基础条件 return 从它。

我猜你想打印出序列,你可以在每个 return

之前 print
def find_collatz_nums(number):
    if number == 1:
        print(int(number))
        return  
    if number % 2 == 0:
        print(int(number), end="->")
        return find_collatz_nums(number/2)
    print(int(number), end="->")
    return find_collatz_nums((3 * number) + 1)

find_collatz_nums(3)
# 3->10->5->16->8->4->2->1

第一个代码片段会导致无限循环,因为没有条件可以避免递归,即显式打印或 return 任何内容。