RecursionError: maximum recursion depth exceeded while calling a Python object. python error

RecursionError: maximum recursion depth exceeded while calling a Python object. python error

有人能帮忙吗,我不知道为什么会出现这个错误:

def sum_list(the_list):
    if not the_list:
        return 0
    else:
        mid = len(the_list) // 2
        return sum_list(the_list[:mid]) + sum_list(the_list[mid:])


print(sum_list([10, 20, 30]))

如果 the_list 的长度为 1(这将在递归调用的某个阶段发生),您将最终陷入无限递归...(mid 将是 0).

你需要解决这个问题以及一个基本案例:

def sum_list(the_list):
    if not the_list:
        return 0
    if len(the_list) == 1:
        return the_list[0]
    else:
        mid = len(the_list) // 2
        return sum_list(the_list[:mid]) + sum_list(the_list[mid:])

我假设这是一个递归练习。 python 提供 sum 来有效地做到这一点。

解决方案

你得到长度为 1 的列表的无限递归,因为 the_list[1 // 2:] 会 return the_list[0:] 这是同一个列表

错误的一些背景知识

调用函数的代价是创建一个新的框架(调用堆栈)。 Python 中有一个软限制,可以防止它创建过多的帧,默认情况下此限制为 1000。

您可以提高此限制,但强烈建议不要这样做,因为它会导致解释器在更高的值上崩溃。

我已经采用了你的功能并添加了一些 print 有助于说明问题所在的语句。

def sum_list(the_list, depth=1):
    print(" The list: ", the_list, "at depth: ", depth)
    if not the_list:
        print(" List empty at depth", depth)
        return 0
    else:
        mid = len(the_list) // 2
        print(" Splitting list at ", depth, "into ", the_list[:mid], " and ", the_list[mid:])
        return sum_list(the_list[:mid], depth +1) + sum_list(the_list[mid:], depth + 1)


print(sum_list([10, 20, 30]))

如果你 运行 这段代码,你将能够在每次调用 sum_list() 时看到 the_list 的值,这有助于说明为什么递归是无限的。

尝试调试函数时,有时在其中粘贴 print 语句以查看它是如何被调用的会很有用。我们期望这个函数最终应该 return 因为它最终会减少到基本情况,这是一个空列表。那会发生吗?

def sum_list(the_list):
    print(f"Summing {the_list}")
    ...

打印:

...
Summing [10]
Summing []
Summing [10]
Summing []
Summing [10]
Summing []
...
RecursionError: maximum recursion depth exceeded while calling a Python object

这告诉我们,对长度为 1 的列表求和可能有问题。让我们逐步了解该逻辑:

>>> the_list = [10]
>>> mid = len(the_list) // 2
>>> the_list[:mid]
[]
>>> the_list[mid:]
[10]

因此,当我们对 [10] 进行递归时,我们最终将再次对 [10] 进行另一个递归调用,这将无限重复。为了解决这个问题,我们需要扩展我们的基本案例:

    if len(the_list) == 1:
        return the_list[0]

请注意,如果我们的基本情况只 return 为零,则递归调用不可能 return 任何不是零和的东西!