9 - Errores comunes en Python al trabajar con listas enlazadas

Errores que conviene detectar a tiempo

Las listas enlazadas combinan referencias y mutabilidad. Esto genera errores frecuentes que pueden causar comportamientos inesperados o ciclos. A continuación se describen los más habituales y cómo prevenirlos en Python.

9.1 Referencias no inicializadas

Usar atributos que no se inicializaron deja referencias con valor indefinido (en Python, AttributeError).

class Nodo:
    def __init__(self, valor):
        self.valor = valor
        # self.sig sin inicializar provoca AttributeError

nodo = Nodo(10)
print(nodo.sig)  # ERROR

# Solución
class NodoSeguro:
    def __init__(self, valor):
        self.valor = valor
        self.sig = None

Inicializa siempre sig en None y valida antes de acceder.

9.2 Perder la referencia a la cabeza

Si reasignas cabeza sin guardar el nodo previo, puedes dejar nodos inaccesibles y depender solo del recolector.

cabeza = Nodo(1)
cabeza.sig = Nodo(2)

# Si hacemos:
cabeza = cabeza.sig  # se pierde el nodo con valor 1

# Forma correcta al eliminar el primero:
victima = cabeza
cabeza = cabeza.sig
victima.sig = None

9.3 Creación accidental de ciclos

Asignar sig al nodo incorrecto puede generar ciclos no deseados y recorridos infinitos.

reco.sig = reco  # ERROR: ciclo inmediato

# Revisa antes de enlazar
if reco.sig is not None:
    # logica normal
    pass

Para detectar ciclos involuntarios, aplica el algoritmo de la tortuga y la liebre (Floyd) en pruebas.

9.4 Mutar mientras se recorre

Modificar enlaces dentro de un while sin almacenar el siguiente nodo puede corromper el recorrido.

reco = cabeza
while reco:
    siguiente = reco.sig  # guardar antes de mutar
    # ... posibles cambios a reco.sig ...
    reco = siguiente

9.5 Compartir nodos entre listas

Reutilizar el mismo nodo en dos listas causa efectos colaterales al modificar una de ellas.

nodo = Nodo(10)
lista_a.cabeza = nodo
lista_b.cabeza = nodo  # ERROR: comparten el mismo nodo

Crea nodos independientes o copia los datos para evitar aliasing.

9.6 Datos mutables compartidos

Almacenar listas o diccionarios en nodos y compartirlos sin copia genera cambios inesperados.

nodo1 = Nodo([])
nodo2 = Nodo(nodo1.valor)  # referencia al mismo objeto lista
nodo1.valor.append(1)
print(nodo2.valor)  # [1], efecto colateral

# Solución: copiar el dato mutable
import copy
nodo2 = Nodo(copy.deepcopy(nodo1.valor))

9.7 Limpieza incompleta

Romper referencias al limpiar la lista acelera la recolección y previene ciclos residuales.

def limpiar(cabeza):
    while cabeza:
        siguiente = cabeza.sig
        cabeza.sig = None
        cabeza = siguiente

9.8 Lista de verificación rápida

  • Inicializa referencias en None y revisa aliasing de nodos.
  • Guarda siempre el siguiente nodo antes de mutar enlaces.
  • Evita ciclos involuntarios y detecta con pruebas (tortuga y liebre).
  • Si usas datos mutables, copia cuando se compartan entre nodos o listas.
  • Implementa una función de limpieza que rompa enlaces para ayudar al GC.