Python Reto #14 — Eliminar duplicados preservando el orden

Nivel: Intermedio
Tema: Listas, sets, orden estable, validación de entradas, complejidad, tests con pytest
Objetivo: Eliminar elementos duplicados de una lista manteniendo el orden original de aparición, un patrón común en limpieza de datos.

Enunciado

Crea una función llamada eliminar_duplicados(lista) que:

  1. Reciba un valor lista.
  2. Si lista es None, devuelva una lista vacía [].
  3. Si lista no es una lista (list), lance TypeError.
  4. Devuelva una nueva lista sin duplicados.
  5. Mantenga el orden original.
  6. Solo debe funcionar con elementos “hashables” (por ejemplo: int, str, tuple).
    • Si aparece un elemento no hashable (por ejemplo, un dict o list), la función debe lanzar TypeError.

Ejemplos

  • eliminar_duplicados([1, 2, 2, 3, 1])[1, 2, 3]
  • eliminar_duplicados(["a", "a", "b", "a"])["a", "b"]
  • eliminar_duplicados([])[]
  • eliminar_duplicados(None)[]
  • eliminar_duplicados([1, {"a": 1}])TypeError

Pistas

  1. Usa un set para recordar qué elementos ya viste.
  2. Recorre la lista y añade al resultado solo si no lo has visto.
  3. Para detectar si algo es hashable, puedes intentar hacer hash(valor) dentro de un try/except.

Solución explicada (paso a paso)

  1. Si lista es None, devolvemos [].
  2. Validamos que lista sea una lista.
  3. Creamos:
    • vistos (un set) para registrar elementos únicos,
    • resultado (una lista) para la salida.
  4. Recorremos cada elemento:
    • verificamos que sea hashable (si no, TypeError),
    • si no está en vistos, lo añadimos a resultado y lo registramos.
  5. Devolvemos resultado.

Ejecuta:

  • pytest -q

Variantes para subir de nivel (opcional)

  1. Permitir elementos no hashables convirtiéndolos a una representación (por ejemplo, json.dumps) (avanzado)
  2. Eliminar duplicados por clave en una lista de diccionarios (patrón real)
  3. Devolver también los duplicados encontrados
  4. Comparar rendimiento vs. dict.fromkeys(lista) (con restricciones)

Lo que aprendiste

  • Cómo eliminar duplicados sin perder orden
  • Uso de set para búsquedas O(1)
  • Qué significa que un objeto sea hashable
  • Validación defensiva en funciones intermedias

Accede al código completo y a los tests en GitHub para ejecutar y modificar la solución localmente.

Continúa con Reto #15 — Leer un CSV y calcular métricas (sin pandas) para practicar procesamiento de archivos y datos tabulares, muy útil en tareas reales.