Profundidad de recurrencia excedida - Lista de doble enlace de Python

Estoy en el proceso de crear un FIFO implementado como una lista doblemente vinculada, pero no sé por qué recibo un error de recursión. He publicado mi código y el error que recibí a continuación. ¡Cualquier ayuda sería muy apreciada!

"""DLList.py"""

class DLList(object):
    """A doubly-linked list

    attributes: nl = node list"""
    def __init__(self, nl=[]):
        self.nl = nl

    def __str__(self):
        return str(self.nl)

    def __len__(self):
        return len(self.nl)

    def append(self, node):
        if not isinstance(node, DLNode):
            raise TypeError
        try:
            node.pn = self.nl[-1]
            node.pn.nn = node
            self.nl.append(node)
        except:
            self.nl.append(node)

    def pop(self):
        rn = self.nl.pop(0)
        try:
            self.nl[0].pn = None
        except:
            pass
        return rn


class DLNode(object):
    """A node in a doubly-linked list.

    attributes: self.pn = previous node, self.data = data, self.nn = next node"""
    def __init__(self, data):
        self.pn = None
        self.data = data
        self.nn = None

    def __str__(self):
        return '[%s, %s, %s]' % (self.pn, self.data, self.nn)


a = DLNode(17)
b = DLNode(15)
c = DLNode(12)
d = DLNode(46)
e = DLNode(46)

ages = DLList()
ages.append(a)
ages.append(b)
ages.append(c)
ages.append(d)
ages.append(e)

print ages.pop()

Recibí este error:

File "C:\python\swampy-2.0\DLList.py", line 43, in __str__
    return '[%s, %s, %s]' % (self.pn, self.data, self.nn)
RuntimeError: maximum recursion depth exceeded

La cuestión es que nunca tuve la intención de usar la recursión, y no puedo entender por qué entré en un bucle recursivo. edades.pop() está destinado a devolver una instancia de DLNode.

preguntado el 27 de julio de 12 a las 16:07

Una cosa, no uses [] como su argumento predeterminado. Cada instancia de DLList hará referencia a lo mismo list instancia en este caso. Usar None y luego busca None y generar una nueva list objeto sobre la marcha en __init__. -

2 Respuestas

Cuando imprime el nodo, está intentando imprimir self.pn y self.nn. Cada uno de ellos es una referencia a otro nodo, que cuando se imprima intentará imprimir su siguiente nodo y su nodo anterior, y así sucesivamente, hasta el infinito. Estás pidiendo imprimir una sala infinita de espejos de nodos.

No tiene nada que haga un seguimiento de lo que ya se ha impreso, por lo que la recursividad continuará para siempre.

Respondido 27 Jul 12, 16:07

Aunque en teoría, esto se detendría cuando .pn or .nn is None como se especifica en el DLNode's __init__(). - Toomai

@Toomai: los enlaces van en ambos sentidos. En una lista de dos elementos, el primer elemento intentará imprimir el segundo elemento, que a su vez intentará imprimir el primero, y así sucesivamente. - Ned Batchelder

Sí, esta no es la mejor manera de imprimir esto de todos modos. Imprimir cualquier elemento imprimirá todos los elementos desde pn y nn ambos son objetos de nodo con sus propios __str__(). Probablemente debería hacer (id(self.pn), self.value, id(self.nn)) en tu DLNode.__str__() en lugar de. - Rayo Silas

También es posible que desee modificar DLList.__str__() para hacer algo como devolver una cadena con la identificación y el valor de cada nodo en la lista. Hacer que solo imprima cada elemento con su propio __str__() como sabe, parece un poco redundantemente detallado. Pero eso es estilo. - Rayo Silas

Bueno, mi sintaxis estaba mal. ;) Arreglé mi comentario. id() obtendrá la identificación interna de cualquier entidad; puede pensar en ello como una dirección de memoria en su mayor parte. Si la memoria no me falla, cuando haces un is comparación en 2 objetos, está comprobando si tienen la misma identificación. - Rayo Silas

Tal vez recomiendo usar collections.deque ¿en cambio? Puede leer su documentación en el bibliotecas. A menos que esté escribiendo su implementación como un ejercicio académico, deque es probablemente mejor.

Respondido 27 Jul 12, 16:07

Fue completamente un ejercicio académico, destinado a introducir el marco deque en python. Gracias por la recomendación, no obstante. - Madison mayo

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.