SolveConPython

Python Reto #17 — Contar ocurrencias con collections.Counter (comparativa)

Nivel: Intermedio
Tema: Diccionarios, collections.Counter, claridad vs. concisión, validación de entradas, tests con pytest
Objetivo: Contar ocurrencias de elementos en una lista y comparar una implementación manual con una solución usando Counter, entendiendo cuándo conviene cada enfoque.

Enunciado

Crea una función llamada contar_ocurrencias(elementos) que:

  1. Reciba un valor elementos.
  2. Si elementos es None, devuelva un diccionario vacío {}.
  3. Si elementos no es una lista (list), lance TypeError.
  4. Devuelva un diccionario donde:
    • las claves sean los elementos de la lista,
    • los valores sean el número de veces que aparece cada elemento.
  5. Asume que los elementos son hashables (por ejemplo, int, str, tuple).

Luego, implementa una segunda versión usando collections.Counter y compara resultados.

Ejemplos

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

Pistas

  1. Implementación manual: usa un diccionario y suma 1 por cada aparición.
  2. Con Counter: importa desde collections y pásale la lista.
  3. Ambas deben producir el mismo resultado para los mismos datos.

Solución explicada (paso a paso)

Enfoque A — Implementación manual

  1. Validamos None y tipo.
  2. Recorremos la lista.
  3. Incrementamos el contador por clave.

Enfoque B — collections.Counter

  1. Validamos None y tipo.
  2. Creamos un Counter(elementos).
  3. Convertimos a dict para devolver un diccionario estándar.

Comparativa:

  • Manual: más verboso, excelente para aprender.
  • Counter: más conciso, estándar y probado para producción.

Ejecuta:

  • pytest -q

Variantes para subir de nivel (opcional)

  1. Frecuencia de palabras (tokenizando strings)
  2. Top-N elementos más frecuentes
  3. Comparar rendimiento (manual vs. Counter) con listas grandes
  4. Soportar normalización (minúsculas, trimming)

Lo que aprendiste

  • Dos maneras de resolver el mismo problema
  • Cuándo preferir claridad vs. concisión
  • Uso práctico de collections.Counter
  • Tests parametrizados con pytest

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

Continúa con Reto #18 — Ordenar una lista de diccionarios por múltiples campos para profundizar en ordenación avanzada y claves personalizadas.