El módulo collections guarda estructuras de datos especializadas que resuelven problemas diarios con menos código y mejor rendimiento. Son el equipo secreto de los Pythonistas experimentados.
Counter: contar sin escribir el bucle
from collections import Counter
palabras = ["python", "es", "genial", "python", "es", "python"]
conteo = Counter(palabras)
print(conteo) # Counter({'python': 3, 'es': 2, 'genial': 1})
print(conteo.most_common(2)) # [('python', 3), ('es', 2)] → top 2
print(Counter("mississippi")) # también cuenta caracteres
Todo el patrón "diccionario de conteo" de la lección de diccionarios, en una línea.
defaultdict: dicts con valor por defecto
from collections import defaultdict
grupos = defaultdict(list) # valor por defecto: lista nueva
personas = [("Ana", "bogota"), ("Luis", "bogota"), ("Sofia", "medellin")]
for nombre, ciudad in personas:
grupos[ciudad].append(nombre) # ¡sin verificar si la clave existe!
print(grupos) # defaultdict(<class 'list'>, {'bogota': ['Ana', 'Luis'], 'medellin': ['Sofia']})
Al acceder a una clave inexistente, defaultdict la crea con el valor por defecto. Desaparece el if ciudad not in grupos: de siempre. Otros defaults útiles: defaultdict(int) para contadores, defaultdict(set) para agrupar sin duplicados.
deque: la cola eficiente
from collections import deque
historial = deque(maxlen=3) # cola con límite: descarta lo viejo
for accion in ["abrir", "editar", "guardar", "cerrar"]:
historial.append(accion)
print(list(historial))
# ['abrir']
# ['abrir', 'editar']
# ['abrir', 'editar', 'guardar']
# ['editar', 'guardar', 'cerrar'] ← el más viejo salió solo
¿Por qué no una lista normal? lista.pop(0) es O(n) — desplaza todos los elementos. En deque, popleft() y appendleft() son O(1): constantes.
cola = deque(["tarea1", "tarea2"])
cola.append("tarea3") # entra por la derecha
siguiente = cola.popleft() # sale por la izquierda → cola FIFO real
Perfecto para: colas de tareas, historiales con límite, algoritmos BFS.
namedtuple: tuplas con nombre
from collections import namedtuple
Punto = namedtuple("Punto", ["x", "y"])
p = Punto(3, 5)
print(p.x, p.y) # 3 5 → por NOMBRE, no por índice
print(p[0]) # 3 → sigue siendo una tupla
La legibilidad de un objeto con la memoria y ligereza de una tupla. (En código moderno mira también dataclasses de la lección intermedia.)
Otras perlas de la stdlib
import heapq
prioridades = [5, 1, 3]
heapq.heapify(prioridades)
print(heapq.heappop(prioridades)) # 1 → el menor siempre arriba
from statistics import mean, median
print(mean([2, 4, 6])) # 4.0
heapq para colas de prioridad, statistics para lo básico sin numpy, bisect para listas ordenadas.
Resumen
Countercuenta y ordena por frecuencia en una líneadefaultdictelimina los "¿existe la clave?" de tus buclesdequepara colas FIFO/limitadas: O(1) en ambos extremosnamedtupleda nombres a tuplas de posición- Conocer la stdlib es la forma más barata de escribir menos código