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 KeyErrorEste 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()) # 100Casos 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")) # FalseSistema 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ística | Counter | defaultdict(int) |
|---|---|---|
| Propósito | Construido específicamente para contar | Diccionario con valor por defecto general |
| Inicialización | Counter(iterable) cuenta en un paso | Requiere bucle manual |
| Claves faltantes | Devuelve 0 | Devuelve 0 |
most_common() | Método integrado | Debe ordenar manualmente |
Aritmética (+, -) | Soportada | No soportada |
Operaciones de conjuntos (&, |) | Soportadas | No soportadas |
elements() | Devuelve iterador expandido | No disponible |
Comportamiento de update() | Suma a los conteos | Reemplaza valores |
| Rendimiento | Implementación C optimizada | Ligeramente más lento |
| Mejor para | Análisis de frecuencia, ops multiconjunto | Ló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.