在使用列表时出现“RuntimeError: maximum recursion depth exceeded in cmp”错误

4
在使用列表时,我遇到了错误RuntimeError: maximum recursion depth exceeded in cmp。更准确地说,针对特定字典p0在我的points列表的特定索引处,p0 in pointspoints.index(p0)方法调用以及points.remove(p0)方法调用都会引发此错误。在错误发生时,points列表包含4700个字典,从一个包含12000个对象的列表中逐个减少一个字典,直到出现错误。p0字典包含对列表中另一个字典的引用,而该字典反过来又包含对p0对象的引用。在任何三个方法调用之前,p0字典以及它所包含的引用出现两次。

这个错误是从哪里来的?

编辑:以下是引发错误的代码:

for roadType in roadTypes:
    points = roadPoints[roadType][:]

    while len(roadTails[roadType]) > 0:
        p0 = roadTails[roadType].pop()

        p1 = p0['next']
        points.remove(p0) # Where the error occurs
        points.remove(p1)

        while True:
            p2 = find(p1, points, 0.01)

            if p2:
                points.remove(p2)

                p3 = p2['next']
                points.remove(p3)

                if p3 in roadTails[roadType]:
                    roadTails[roadType].remove(p3)
                    break
                else:
                    p0, p1 = p2, p3
                    continue

            else: break

这里是find的定义,其中dist计算两点之间的距离。
def find(p1, points, tolerance = 0.01):
    for p2 in points:
        if dist(p2['coords'], p1['coords']) <= tolerance:
            return p2
    return False

以下是错误的完整回溯信息:

Traceback (most recent call last):
  File "app.py", line 314, in <module>
    points.remove(p0) # Where the error occurs
RuntimeError: maximum recursion depth exceeded in cmp

2
您能给我们展示一些代码吗? - Eric
1
我仍然没有看到任何递归。给我们展示更多的代码!find来自哪里? - Eric
你能在代码开头添加 sys.setrecursionlimit(20) 并发布完整的回溯吗? - Eric
@Morhaus:它真的只给你一个级别吗? - Eric
1
@Eric:错误似乎是由列表对象的本地方法引起的。回溯没有显示更多的层级。 - Alexandre Kirszenberg
显示剩余3条评论
1个回答

10

可能你有一个循环结构,其中一个字典通过一系列的'next'引用自身,就像这样:

>>> a = {}
>>> b = {}
>>> a['next'] = b
>>> b['next'] = a
>>> a == b
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
RuntimeError: maximum recursion depth exceeded in cmp
如果你打印出这个字典,循环引用会显示为...:
>>> a
{'next': {'next': {...}}}
也许这可以帮助找到字典中有问题的部分。

糟糕,我差点就做到了!**+1** - Eric
这的确是事实,但我不明白为什么列表的本地方法会使用'=='而不是'is',例如'remove'和'index'等方法?我应该使用什么类型的对象来包含我的数据? - Alexandre Kirszenberg
2
@Morhaus: 这就是列表和字典语义的工作原理。也许最好定义自己的class来代替使用dict。如果您没有定义任何特殊比较方法,则对于这些自定义对象,==将与is相同。 - sth

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接