Collections

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.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *