Python es conocido por su legibilidad y versatilidad. Si bien las listas (list
) y los diccionarios (dict
) son estructuras de datos fundamentales, la biblioteca collections
ofrece una serie de contenedores especializados que pueden simplificar tu código y mejorar el rendimiento en situaciones específicas.
¿Qué es collections?
La biblioteca collections
forma parte de la librería estándar de Python. Proporciona tipos de datos contenedores alternativos a los que ya conocemos (listas, tuplas, diccionarios, conjuntos), ofreciendo funcionalidades adicionales y optimizaciones para casos de uso particulares. No es necesario instalarla; simplemente importa el módulo collections
en tu código así:
import collections
Tuplas con Nombres (namedtuple)
Las tuplas son inmutables y se definen por su posición. Esto puede dificultar la lectura del código, especialmente cuando tienes muchas variables relacionadas, namedtuple
resuelve este problema al permitirte asignar nombres a las posiciones de una tupla.
# Definimos un namedtuple llamado 'punto' con campos x e y
punto = collections.namedtuple('punto', ['x', 'y'])
# Creamos una instancia de punto
p = punto(10, 20)
# Accedemos a los valores por nombre
print(p.x) # 10
print(p.y) # 20
# También podemos acceder por índice como una tupla normal
print(p[0]) # 10
namedtuple
es ideal para representar registros de datos, coordenadas, o cualquier estructura donde el significado de cada elemento sea importante. Mejora la legibilidad y reduce los errores al eliminar la necesidad de recordar las posiciones de los elementos.
Colas Doblemente Enlazadas (deque)
Las listas son eficientes para acceder a elementos por índice, pero insertar o eliminar elementos al principio de una lista es costoso porque requiere desplazar todos los demás elementos. deque
proporciona una cola doblemente enlazada que permite inserciones y eliminaciones rápidas tanto al principio como al final.
# Creamos un deque
d = collections.deque()
# Agregamos elementos al final
d.append(1)
d.append(2)
d.append(3)
# Agregamos elementos al principio
d.appendleft(0)
d.appendleft(-1)
print(d) # deque([-1, 0, 1, 2, 3])
# Eliminamos elementos del final y del principio
print(d.pop()) # 3
print(d.popleft()) # -1
print(d) # deque([0, 1, 2])
deque
es perfecto para implementar colas, pilas y otros algoritmos que requieren inserciones/eliminaciones eficientes en ambos extremos.
Contando Ocurrencias (Counter)
A veces necesitas contar cuántas veces aparece cada elemento en una secuencia. Counter
simplifica esta tarea al crear un diccionario donde las claves son los elementos y los valores son la suma de veces.
# Creamos un Counter a partir de una lista
mi_lista = ['a', 'b', 'c', 'a', 'b', 'a']
contador = collections.Counter(mi_lista)
print(contador) # Counter({'a': 3, 'b': 2, 'c': 1})
# Accedemos al conteo de un elemento específico
print(contador['a']) # 3
# Obtener los elementos más comunes
print(contador.most_common(2)) # [('a', 3), ('b', 2)]
# Obtenemos los elementos clave, valor
for x,y in contador.items():
print(x,y)
Counter
es muy útil para analizar datos o encontrar las palabras más frecuentes en un texto .
Diccionarios con Orden Garantizado (OrderedDict)
En versiones anteriores a Python 3.7, los diccionarios no garantizaban el orden de inserción. OrderedDict
mantenía el orden en que se insertaron las claves. A partir de Python 3.7, los diccionarios estándar conservan el orden de inserción, por lo que OrderedDict
es menos crucial, pero aún puede ser útil para compatibilidad con versiones anteriores o cuando necesitas funcionalidades específicas relacionadas con el orden.
# Creamos un OrderedDict
od = collections.OrderedDict()
# Insertamos elementos
od['a'] = 1
od['b'] = 2
od['c'] = 3
# Iteramos sobre las claves en el orden de inserción
for clave, valor in od.items():
print(clave, valor) # Output: a 1, b 2, c 3
Diccionarios con Valores Predeterminados (defaultdict)
defaultdict
es un diccionario que proporciona un valor predeterminado para las claves que aún no existen. Esto evita errores KeyError
cuando intentas acceder a una clave inexistente.
# Creamos un defaultdict con el tipo int como valor predeterminado (inicializado a 0)
mi_defaultdict = collections.defaultdict(int)
# Incrementamos el conteo de 'a'
mi_defaultdict['a'] += 1
# Intentar acceder a una clave inexistente no genera un error
print(mi_defaultdict['b']) # 0 (el valor predeterminado es 0)
defaultdict
simplifica el código al eliminar la necesidad de verificar si una clave existe antes de acceder o modificar su valor. Es especialmente útil para contar elementos, agrupar datos y construir estructuras de datos complejas.