Skip to content

Python Counter: Contar y Tabular Elementos con collections.Counter

Updated on

Contar las ocurrencias de elementos en una lista, caracteres en una cadena o palabras en un documento es una de las tareas más comunes en programación. Hacerlo manualmente significa escribir bucles, inicializar diccionarios y manejar claves faltantes con condicionales o llamadas .get(). Este código repetitivo oscurece tu intención real, introduce bugs y te ralentiza cada vez que necesitas un conteo de frecuencia.

collections.Counter de Python elimina esta fricción por completo. Cuenta objetos hashables en una sola línea, proporciona métodos integrados para encontrar los elementos más comunes y soporta operaciones aritméticas para comparar distribuciones de frecuencia. Esta guía cubre todo lo que necesitas para usar Counter efectivamente, desde el conteo básico hasta operaciones avanzadas de multiconjuntos.

📚

¿Qué es collections.Counter?

Counter es una subclase de diccionario en el módulo collections de Python diseñada específicamente para contar objetos hashables. Cada elemento se almacena como una clave de diccionario y su conteo se almacena como el valor correspondiente.

from collections import Counter
 
fruits = ['apple', 'banana', 'apple', 'cherry', 'banana', 'apple']
count = Counter(fruits)
print(count)
# Counter({'apple': 3, 'banana': 2, 'cherry': 1})

Crear un Counter

Counter acepta múltiples tipos de entrada, haciéndolo flexible para diferentes fuentes de datos.

from collections import Counter
 
# Desde una lista
colors = Counter(['red', 'blue', 'red', 'green', 'blue', 'red'])
print(colors)  # Counter({'red': 3, 'blue': 2, 'green': 1})
 
# Desde una cadena (cuenta cada carácter)
letters = Counter('mississippi')
print(letters)  # Counter({'s': 4, 'i': 4, 'p': 2, 'm': 1})
 
# Desde un diccionario
inventory = Counter({'apples': 15, 'oranges': 10, 'bananas': 7})
 
# Desde argumentos con nombre
stock = Counter(laptops=5, monitors=12, keyboards=30)

Acceder a los Conteos

Indexación Básica

Accede a los conteos como un diccionario regular, pero las claves faltantes devuelven 0 en lugar de lanzar KeyError:

from collections import Counter
 
c = Counter(['a', 'b', 'a'])
print(c['a'])  # 2
print(c['z'])  # 0 (¡sin KeyError!)
 
# Comparar con el comportamiento de dict regular
d = {'a': 2, 'b': 1}
# d['z']  # Lanzaría KeyError

Este comportamiento de cero por defecto elimina la necesidad de .get(key, 0) o defaultdict(int) en muchos escenarios de conteo.

Obtener Todos los Elementos

El método elements() devuelve un iterador sobre los elementos, repitiendo cada uno tantas veces como su conteo:

from collections import Counter
 
c = Counter(a=3, b=2, c=1)
print(list(c.elements()))
# ['a', 'a', 'a', 'b', 'b', 'c']

El Método most_common()

El método most_common() devuelve elementos ordenados por frecuencia.

from collections import Counter
 
text = "to be or not to be that is the question"
word_freq = Counter(text.split())
 
# Todos los elementos ordenados por frecuencia
print(word_freq.most_common())
# [('to', 2), ('be', 2), ('or', 1), ('not', 1), ...]
 
# Solo los Top N elementos
log_levels = Counter(['INFO', 'WARNING', 'INFO', 'ERROR', 'INFO', 'DEBUG',
                      'WARNING', 'INFO', 'ERROR', 'INFO'])
print(log_levels.most_common(2))
# [('INFO', 5), ('WARNING', 2)]
 
# Menos comunes (slice inverso)
print(log_levels.most_common()[-2:])
# [('DEBUG', 1), ('ERROR', 2)]

Operaciones Aritméticas de Counter

Counter soporta operaciones aritméticas y de conjuntos para combinar y comparar distribuciones de frecuencia.

from collections import Counter
 
morning = Counter(coffee=10, tea=5, juice=3)
afternoon = Counter(coffee=8, tea=7, water=4)
 
# Suma: combina conteos
total = morning + afternoon
print(total)  # Counter({'coffee': 18, 'tea': 12, 'water': 4, 'juice': 3})
 
# Resta: mantiene solo conteos positivos
stock = Counter(apples=20, oranges=15, bananas=10)
sold = Counter(apples=8, oranges=15, bananas=12)
remaining = stock - sold
print(remaining)  # Counter({'apples': 12})
 
# Intersección (&): mínimo de los conteos correspondientes
a = Counter(apple=3, banana=2, cherry=5)
b = Counter(apple=1, banana=4, cherry=2)
print(a & b)  # Counter({'cherry': 2, 'banana': 2, 'apple': 1})
 
# Unión (|): máximo de los conteos correspondientes
print(a | b)  # Counter({'cherry': 5, 'banana': 4, 'apple': 3})
 
# + unario: elimina conteos cero y negativos
c = Counter(a=3, b=0, c=-2)
print(+c)  # Counter({'a': 3})

Actualizar y Sustraer

from collections import Counter
 
# update() SUMA conteos (a diferencia de dict.update que reemplaza)
c = Counter(a=3, b=1)
c.update(['a', 'b', 'b', 'c'])
print(c)  # Counter({'a': 4, 'b': 3, 'c': 1})
 
# subtract() sustrae conteos (mantiene cero y negativos)
c = Counter(a=4, b=2, c=0)
c.subtract(Counter(a=1, b=3, c=2))
print(c)  # Counter({'a': 3, 'b': -1, 'c': -2})
 
# total() devuelve la suma de todos los conteos (Python 3.10+)
inventory = Counter(widgets=50, gadgets=30, gizmos=20)
print(inventory.total())  # 100

Casos de Uso Prácticos

Análisis de Frecuencia de Palabras

from collections import Counter
import re
 
text = """
Python is a versatile programming language. Python is used for web development,
data science, machine learning, and automation. Python's simplicity makes it
a favorite among developers.
"""
 
words = re.findall(r'\b[a-z]+\b', text.lower())
word_freq = Counter(words)
 
print("Top 5 most frequent words:")
for word, count in word_freq.most_common(5):
    print(f"  {word}: {count}")

Detección de Anagramas

from collections import Counter
 
def are_anagrams(word1, word2):
    return Counter(word1.lower()) == Counter(word2.lower())
 
print(are_anagrams("listen", "silent"))  # True
print(are_anagrams("hello", "world"))    # False

Sistema de Conteo de Votos

from collections import Counter
 
votes = ['Alice', 'Bob', 'Alice', 'Charlie', 'Bob', 'Alice',
         'Charlie', 'Alice', 'Bob', 'Alice']
 
results = Counter(votes)
winner, winning_votes = results.most_common(1)[0]
total_votes = sum(results.values())
 
print(f"Election Results (Total votes: {total_votes}):")
for candidate, count in results.most_common():
    percentage = (count / total_votes) * 100
    print(f"  {candidate}: {count} votes ({percentage:.1f}%)")
print(f"\nWinner: {winner} with {winning_votes} votes")

Análisis de Archivos de Log

from collections import Counter
import re
 
log_entries = [
    "2026-02-10 08:15:00 ERROR Database connection failed",
    "2026-02-10 08:15:01 INFO Retrying connection",
    "2026-02-10 08:15:02 ERROR Database connection failed",
    "2026-02-10 08:16:00 WARNING Disk usage at 85%",
    "2026-02-10 08:17:00 INFO Request processed",
    "2026-02-10 08:18:00 ERROR API timeout",
]
 
levels = Counter(
    re.search(r'(INFO|WARNING|ERROR)', line).group()
    for line in log_entries
)
print("Log Level Distribution:")
for level, count in levels.most_common():
    print(f"  {level}: {count}")

Counter vs defaultdict(int): Cuándo Usar Cuál

CaracterísticaCounterdefaultdict(int)
PropósitoConstruido específicamente para contarDiccionario con valor por defecto general
InicializaciónCounter(iterable) cuenta en un pasoRequiere bucle manual
Claves faltantesDevuelve 0Devuelve 0
most_common()Método integradoDebe ordenar manualmente
Aritmética (+, -)SoportadaNo soportada
Operaciones de conjuntos (&, |)SoportadasNo soportadas
elements()Devuelve iterador expandidoNo disponible
Comportamiento de update()Suma a los conteosReemplaza valores
RendimientoImplementación C optimizadaLigeramente más lento
Mejor paraAnálisis de frecuencia, ops multiconjuntoLógica de valor por defecto personalizada

Usa Counter cuando tu objetivo principal es contar elementos o comparar distribuciones de frecuencia. Usa defaultdict(int) cuando el conteo es secundario a un patrón de estructura de datos más amplio.

Visualizar Distribuciones de Frecuencia

Después de contar elementos con Counter, a menudo querrás visualizar la distribución. Para exploración interactiva de distribuciones de frecuencia, PyGWalker (opens in a new tab) convierte un DataFrame de pandas en una interfaz interactiva estilo Tableau directamente dentro de Jupyter:

from collections import Counter
import pandas as pd
import pygwalker as pyg
 
# Convertir Counter a DataFrame
data = Counter("abracadabra")
df = pd.DataFrame(data.items(), columns=['Character', 'Count'])
 
# Lanzar visualización interactiva
walker = pyg.walk(df)

Esto es especialmente útil cuando tienes contadores grandes y quieres filtrar, ordenar y explorar distribuciones de frecuencia interactivamente.

FAQ

¿Qué hace collections.Counter en Python?

collections.Counter es una subclase de diccionario que cuenta objetos hashables. Le pasas cualquier iterable y devuelve un objeto tipo diccionario donde las claves son los elementos y los valores son sus conteos. Proporciona métodos como most_common() para análisis de frecuencia, operadores aritméticos para combinar conteos y devuelve cero para claves faltantes en lugar de lanzar un KeyError.

¿Cómo cuento ocurrencias de elementos en una lista usando Python Counter?

Importa Counter de collections y pasa tu lista directamente: Counter(['a', 'b', 'a', 'c']) devuelve Counter({'a': 2, 'b': 1, 'c': 1}). Para obtener conteos específicos, indexa con el elemento: counter['a'] devuelve 2. Para los elementos más frecuentes, usa counter.most_common(n).

¿Cuál es la diferencia entre Counter y un diccionario regular para contar?

Counter está construido específicamente para contar: cuenta un iterable completo en una llamada, devuelve 0 para claves faltantes en lugar de KeyError, tiene most_common() para frecuencias ordenadas, soporta operaciones aritméticas (+, -, &, |), e incluye update() que suma a los conteos en lugar de reemplazarlos. Un diccionario regular requiere construcción manual de bucles y carece de estas características.

¿Puedo sustraer o sumar dos objetos Counter?

Sí. El operador + combina conteos: Counter(a=3) + Counter(a=1) produce Counter({'a': 4}). El operador - sustrae conteos y descarta resultados cero o negativos. El operador & da el mínimo (intersección) y | da el máximo (unión) de los conteos correspondientes. Para sustracción que preserve conteos negativos, usa el método subtract() en su lugar.

¿Es Python Counter eficiente para grandes conjuntos de datos?

Sí. Counter está implementado en código C optimizado en CPython, haciéndolo más rápido que bucles manuales de Python para contar. Crear un Counter desde un iterable es O(n). Acceder a conteos individuales es O(1). La operación most_common(k) usa un heap internamente para eficiencia O(n log k) cuando solo necesitas los top-k elementos.

Conclusión

collections.Counter de Python es la herramienta estándar para contar elementos y realizar análisis de frecuencia. Reemplaza el conteo manual con diccionarios por una sola llamada al constructor, proporciona most_common() para clasificación instantánea y soporta operaciones aritméticas que hacen triviales las comparaciones de multiconjuntos. Ya sea que estés analizando frecuencias de palabras, contando votos, gestionando inventario o analizando archivos de log, Counter maneja el conteo para que puedas enfocarte en la lógica que importa.

📚