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:
- Reciba un valor
elementos. - Si
elementosesNone, devuelva un diccionario vacío{}. - Si
elementosno es una lista (list), lanceTypeError. - Devuelva un diccionario donde:
- las claves sean los elementos de la lista,
- los valores sean el número de veces que aparece cada elemento.
- 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
- Implementación manual: usa un diccionario y suma 1 por cada aparición.
- Con
Counter: importa desdecollectionsy pásale la lista. - Ambas deben producir el mismo resultado para los mismos datos.
Solución explicada (paso a paso)
Enfoque A — Implementación manual
- Validamos
Noney tipo. - Recorremos la lista.
- Incrementamos el contador por clave.
Enfoque B — collections.Counter
- Validamos
Noney tipo. - Creamos un
Counter(elementos). - Convertimos a
dictpara 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)
- Frecuencia de palabras (tokenizando strings)
- Top-N elementos más frecuentes
- Comparar rendimiento (manual vs.
Counter) con listas grandes - 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.