Listas y Diccionarios en Python
Orquestar infraestructura no es gestionar un servidor. Es gestionar cientos, con configuraciones distintas, en regiones distintas, al mismo tiempo. Para meter esa multiplicidad en código, Python te da dos estructuras base: listas y diccionarios.
Ninguna de las dos te obliga a declarar el tamaño de antemano. Si vienes de C o Java, eso ya es una victoria.
Las Listas: Colecciones Ordenadas
Una lista es una colección ordenada e iterable. Cada elemento tiene un índice numérico que arranca en 0, y puedes meter dentro lo que quieras sin declarar tipos.
# Definir una lista de zonas de disponibilidad en AWS
az_list = ['us-east-1a', 'us-east-1b', 'us-east-1c', 'us-west-2a']
# Iterar sobre la lista de zonas para un despliegue
print('=== Iterando zonas para el despliegue ===')
for az in az_list:
print(f'Aprovisionando recurso en: {az}')
# Acceder a un valor específico mediante su índice
print('=== Inspeccionando la zona primaria ===')
print(az_list[0]) # Salida: us-east-1a
# Añadir una nueva zona dinámica
az_list.append('eu-central-1a')
print(az_list)
Cuando necesitas balanceo de carga o selecciones aleatorias, el módulo random de la biblioteca estándar hace el trabajo sin necesidad de instalar nada extra.
from random import randrange
az_list = ['us-east-1a', 'us-east-1b', 'us-east-1c']
# Calcular la longitud (len) y elegir un índice aleatorio
indice_objetivo = randrange(0, len(az_list))
print(f'Balanceador asignando tráfico inicial a: {az_list[indice_objetivo]}')
Las listas tienen bastantes métodos. Puedes ver todos con dir(list). En automatización los que realmente aparecen son tres: .sort() para ordenar, .reverse() para invertir la colección, y .pop() para sacar el último elemento. .pop() es el más útil cuando tratas la lista como una cola de trabajo porque te da el elemento que retiras, no solo lo borra.
az_list = ['us-west-1', 'eu-west-1', 'us-east-1', 'ap-northeast-1']
# Orden alfabético
az_list.sort()
print(f"Zonas ordenadas: {az_list}")
# Invertir la colección resultante
az_list.reverse()
print(f"Zonas invertidas: {az_list}")
# Eliminar y recuperar la última zona (última de la lista invertida)
zona_procesada = az_list.pop()
print(f"La zona {zona_procesada} ha sido eliminada de la cola de procesamiento.")
Diccionarios: Datos Estructurados como Clave/Valor
La lista indexa por posición. El diccionario indexa por nombre. Esa diferencia parece pequeña hasta que intentas rastrear el puerto de un nodo por su número de fila en lugar de por su clave 'port', y te das cuenta de que no tiene ningún sentido. Los pares clave/valor se leen casi igual que JSON o YAML, y el acceso es O(1).
# Representar la configuración de un nodo de base de datos
nodo_db = {
'hostname': 'db-cluster-01',
'engine': 'postgres',
'version': '15.4',
'port': 5432,
'backup_enabled': True,
'max_connections': 1000
}
print('=== Metadatos del nodo ===')
print(f"Conectar mediante puerto: {nodo_db['port']}")
print(f"Motor: {nodo_db['engine']} v{nodo_db['version']}")
En la práctica nadie maneja un solo nodo. Lo que tienes delante es siempre una lista de diccionarios: un arreglo de objetos, exactamente el formato que devuelve cualquier API REST sin que tengas que transformar nada.
# Un clúster representado como una lista de diccionarios
infraestructura = [
{
'id': 'web-01',
'role': 'frontend',
'status': 'running',
'ip': '10.0.0.5'
},
{
'id': 'web-02',
'role': 'frontend',
'status': 'draining',
'ip': '10.0.0.6'
},
{
'id': 'api-01',
'role': 'backend',
'status': 'running',
'ip': '10.0.1.15'
}
]
print('=== Reporte del Estado del Clúster ===')
# Extraer la IP del nodo api-01 accediendo al índice de lista [2] y la clave ['ip']
print(f"Dirección IP del backend maestro: {infraestructura[2]['ip']}")
print('-'*50)
# Iterar y filtrar los nodos del clúster
for nodo in infraestructura:
print(f"Nodo: {nodo['id']:<10} | Rol: {nodo['role']:<10} | Estado: {nodo['status'].upper()}")
La notación lista[indice]['clave'] es el patrón central de este bloque. Domínalo y cualquier respuesta JSON queda al alcance sin importar la profundidad de la estructura.