Domina la organización, búsqueda y gestión de datos con la estructura de mapeo clave-valor más potente y versátil de Python.
En el vasto universo de la programación, a menudo necesitamos asociar información de una manera que no sea simplemente secuencial. Queremos poder buscar un dato específico utilizando un identificador único, tal como buscarías una palabra en un diccionario para encontrar su significado, o el nombre de un elemento en la tabla periódica para conocer sus propiedades. Para esta tarea, Python nos ofrece una estructura de datos excepcionalmente poderosa y eficiente: el diccionario (dict). [cite: 11, 12]
Un diccionario es una colección que almacena sus elementos en pares de clave-valor. Cada clave es única y sirve como una "etiqueta" o "índice" para acceder a su valor correspondiente. [cite: 14, 15]
Entender el modelo clave-valor es fundamental para dominar los diccionarios[cite: 63]:
clave: valor forma una "entrada" o "ítem" en el diccionario. [cite: 67, 176]
Por ejemplo, en un diccionario que almacena las masas atómicas de elementos químicos: la clave podría ser el símbolo del elemento (ej: "He" para Helio) y el valor sería su masa atómica (ej: 4.002602).
💡 ¿Por qué $O(1)$ es importante? [cite: 34, 36] La notación $O(1)$ (leída como "Orden de 1" o "tiempo constante") significa que la operación toma aproximadamente la misma cantidad de tiempo, sin importar cuán grande sea el diccionario. Ya sea que tengas 10 ítems o 10 millones, encontrar un valor por su clave será increíblemente rápido. Esto contrasta con las listas, donde buscar un elemento puede requerir revisar cada ítem (operación $O(n)$).
Python te da varias maneras flexibles de crear diccionarios:
{ } (Forma Literal):Es la forma más común y visual. Los pares clave: valor se separan por comas, todo encerrado en llaves.
# Diccionario de densidades de algunos metales (g/cm³) - Química/Física
densidades_metales = {
"Hierro": 7.874,
"Cobre": 8.96,
"Aluminio": 2.70,
"Oro": 19.32
}
print(f"Densidades: {densidades_metales}")
# Diccionario para representar un vector en 2D (Matemáticas)
vector_2d = {"x": 3.5, "y": -1.2}
print(f"Vector: {vector_2d}")
# Diccionario vacío con llaves
dic_vacio1 = {}
print(f"Diccionario vacío con {{}}: {dic_vacio1}, Tipo: {type(dic_vacio1)}")
dict():El constructor dict() es muy versátil:
dict(): Crea un diccionario vacío.dict(clave1=valor1, clave2=valor2, ...): Usando argumentos de palabra clave (las claves deben ser nombres de identificador válidos).dict(iterable_de_pares): A partir de un iterable que produce pares clave-valor (ej: una lista de tuplas [('a', 1), ('b', 2)]).dict(otro_diccionario): Crea una copia superficial de otro diccionario.# Con argumentos de palabra clave (para datos de una simulación física)
simulacion_params = dict(
tiempo_total_s=100,
paso_integracion_s=0.01,
metodo_integracion="Runge-Kutta"
)
print(f"Parámetros de simulación: {simulacion_params}")
# Desde una lista de tuplas (ej. notas musicales y sus frecuencias en Hz - Música)
notas_frecuencias_lista = [("La4", 440.00), ("Do5", 523.25), ("Sol3", 196.00)]
frecuencias_afinacion = dict(notas_frecuencias_lista)
print(f"Frecuencias de afinación: {frecuencias_afinacion}")
# Diccionario vacío con dict()
dic_vacio2 = dict()
print(f"Otro vacío con dict(): {dic_vacio2}")
dict.fromkeys(iterable, valor_opcional):
Crea un nuevo diccionario donde las claves se toman de un iterable y todas las claves apuntan inicialmente al mismo valor_opcional (que por defecto es None si no se especifica).
# Para inicializar el inventario de especímenes en un estudio biológico
especimenes_a_colectar = ("PlantaA", "InsectoB", "HongoC")
inventario_colecta = dict.fromkeys(especimenes_a_colectar, 0) # Cantidad inicial 0
print(f"Inventario inicial de colecta: {inventario_colecta}")
# Salida: {'PlantaA': 0, 'InsectoB': 0, 'HongoC': 0}
# Para registrar la asistencia de alumnos a una clase (valor inicial False)
lista_alumnos_clase = ["Ana", "Luis", "Eva"]
asistencia_clase = dict.fromkeys(lista_alumnos_clase, False)
print(f"Registro de asistencia inicial: {asistencia_clase}")
La principal forma de usar un diccionario es obtener el valor asociado a una clave.
[clave] (Acceso Directo):
Si la clave existe, obtienes su valor. Si la clave no existe, Python lanza un error KeyError. [cite: 75, 181]
# Datos de un experimento de Óptica (Física)
experimento_optica = {
"fuente_luz": "Láser He-Ne",
"longitud_onda_nm": 632.8,
"potencia_mW": 5.0,
"angulo_incidencia_grados": 30
}
longitud_onda = experimento_optica["longitud_onda_nm"]
print(f"Longitud de onda utilizada: {longitud_onda} nm")
# print(experimento_optica["polarizacion"]) # Esto daría KeyError
get(clave, valor_por_defecto_opcional):
Es una forma más segura si no estás seguro de que una clave exista. No lanza KeyError. [cite: 76, 110, 188]
clave existe, devuelve su valor.clave no existe, devuelve None (por defecto).clave no existe y proporcionas un valor_por_defecto_opcional, devuelve ese valor.# Inventario de instrumentos musicales (Música)
instrumentos_stock = {"Guitarra": 10, "Piano": 3, "Batería": 5}
stock_guitarra = instrumentos_stock.get("Guitarra")
print(f"Stock de Guitarras: {stock_guitarra}") # Salida: 10
stock_violin = instrumentos_stock.get("Violín", 0) # Si no hay violines, asumimos 0
print(f"Stock de Violines: {stock_violin}") # Salida: 0
stock_bajo = instrumentos_stock.get("Bajo") # No existe, devuelve None
print(f"Stock de Bajos: {stock_bajo}") # Salida: None
setdefault(clave, valor_por_defecto_opcional):
Este método es interesante: si la clave existe, devuelve su valor (como get()). Pero si la clave no existe, la inserta en el diccionario con el valor_por_defecto_opcional (o None si no se especifica el valor por defecto) y luego devuelve ese valor por defecto. [cite: 110, 122, 193]
# Conteo de frecuencia de palabras en un texto (Lingüística/Procesamiento de Texto)
conteo_palabras = {}
texto_ejemplo = "la casa es azul y la ventana es azul"
palabras = texto_ejemplo.lower().split()
for palabra in palabras:
# Si la palabra no está, la añade con 0 y devuelve 0. Luego se suma 1.
# Si ya está, devuelve su conteo actual. Luego se suma 1.
conteo_palabras[palabra] = conteo_palabras.setdefault(palabra, 0) + 1
print(f"Frecuencia de palabras: {conteo_palabras}")
# Salida: {'la': 2, 'casa': 1, 'es': 2, 'azul': 2, 'y': 1, 'ventana': 1}
Puedes añadir un nuevo par o modificar el valor de una clave existente usando el operador de asignación = con la clave entre corchetes. [cite: 20, 81, 182]
# Datos de un satélite artificial (Astronomía/Ingeniería)
satelite_ISS = {
"nombre": "Estación Espacial Internacional",
"orbita_km": 408,
"velocidad_km_s": 7.66
}
print(f"ISS Original: {satelite_ISS}")
# Modificar la altura de la órbita
satelite_ISS["orbita_km"] = 412
print(f"ISS Órbita Actualizada: {satelite_ISS}")
# Añadir nueva información
satelite_ISS["tripulacion_maxima"] = 7
satelite_ISS["pais_principal_operador"] = "Internacional"
print(f"ISS con más datos: {satelite_ISS}")
También puedes usar el método update(otro_diccionario_o_iterable_de_pares) para añadir o actualizar múltiples ítems a la vez. Si las claves ya existen, sus valores se actualizan; si no, se añaden los nuevos pares. [cite: 110, 121, 192]
# Propiedades de un compuesto químico (Química)
compuesto_etanol = {"formula": "C2H5OH", "estado_fisico": "Líquido"}
propiedades_adicionales = {"punto_ebullicion_C": 78.37, "densidad_g_cm3": 0.789}
compuesto_etanol.update(propiedades_adicionales)
compuesto_etanol.update(estado_fisico="Líquido incoloro") # Actualiza un valor existente
print(f"Etanol completo: {compuesto_etanol}")
Python ofrece varias formas de eliminar ítems:
del diccionario[clave]: Elimina el ítem. Lanza KeyError si la clave no existe. [cite: 184]pop(clave, valor_por_defecto_opcional): Elimina la clave y devuelve su valor. Si la clave no existe, devuelve valor_por_defecto (o lanza KeyError si no se da). [cite: 110, 189]popitem(): Elimina y devuelve un par (clave, valor). En Python 3.7+, es el último ítem insertado (LIFO). Lanza KeyError si está vacío. [cite: 110, 190]clear(): Elimina todos los ítems. [cite: 110, 191]# Registro de mediciones de un sensor (Física/Ingeniería)
mediciones_sensor = {
"temperatura_C": 25.5,
"humedad_relativa_porc": 60.2,
"presion_hPa": 1012.5,
"timestamp_ultimo": "2024-05-30 10:00:00"
}
print(f"Mediciones iniciales: {mediciones_sensor}")
# Eliminar 'presion_hPa' con del
if "presion_hPa" in mediciones_sensor: # Buena práctica verificar antes
del mediciones_sensor["presion_hPa"]
print(f"Tras del: {mediciones_sensor}")
# Eliminar 'humedad_relativa_porc' con pop() y obtener su valor
humedad = mediciones_sensor.pop("humedad_relativa_porc", "No registrada")
print(f"Humedad eliminada: {humedad}. Mediciones: {mediciones_sensor}")
# Eliminar el último ítem (timestamp_ultimo en Python 3.7+)
if mediciones_sensor: # Verificar si no está vacío
clave_elim, valor_elim = mediciones_sensor.popitem()
print(f"Eliminado con popitem(): '{clave_elim}': {valor_elim}")
print(f"Mediciones tras popitem(): {mediciones_sensor}")
# Vaciar todas las mediciones
mediciones_sensor.clear()
print(f"Mediciones finales: {mediciones_sensor}")
keys(), values(), items()
Estos métodos devuelven objetos especiales llamados "vistas de diccionario". Una vista es dinámica: si el diccionario cambia, la vista refleja esos cambios. Son iterables, lo que te permite usarlas en bucles for. [cite: 78, 79, 110, 185, 186, 187]
diccionario.keys() : Devuelve una vista de todas las claves.diccionario.values() : Devuelve una vista de todos los valores.diccionario.items() : Devuelve una vista de todos los pares clave-valor (como tuplas (clave, valor)).# Ejemplo: Información nutricional de alimentos (Biología/Nutrición)
info_nutricional_por_100g = {
"Manzana": {"calorias": 52, "carbohidratos_g": 14, "fibra_g": 2.4},
"Pollo (pechuga)": {"calorias": 165, "proteina_g": 31, "grasa_g": 3.6},
"Lentejas (cocidas)": {"calorias": 116, "proteina_g": 9, "fibra_g": 7.9}
}
print("--- Alimentos Registrados (Claves) ---")
for alimento in info_nutricional_por_100g.keys():
print(f"- {alimento}")
print("\n--- Datos Nutricionales (Valores) ---")
# Aquí los valores son otros diccionarios
for datos_completos_alimento in info_nutricional_por_100g.values():
print(f"- Calorías: {datos_completos_alimento.get('calorias', 'N/A')}, Proteínas: {datos_completos_alimento.get('proteina_g', 'N/A')}g")
print("\n--- Ficha Nutricional Completa (Items) ---")
for alimento, detalles_nutricionales in info_nutricional_por_100g.items():
print(f"\nAlimento: {alimento}")
for nutriente, valor in detalles_nutricionales.items():
print(f" - {nutriente.replace('_', ' ').capitalize()}: {valor}")
# Convertir vistas a listas si necesitas una copia estática
lista_alimentos = list(info_nutricional_por_100g.keys())
print(f"\nLista estática de alimentos: {lista_alimentos}")
Recorrer los elementos de un diccionario es una tarea común. Python te lo facilita con bucles for y los métodos de vista.
# Diccionario de instrumentos musicales y su clasificación (Música)
instrumentos_clasificacion = {
"Violín": "Cuerda frotada", "Guitarra": "Cuerda pulsada",
"Piano": "Cuerda percutida", "Flauta": "Viento madera", "Trompeta": "Viento metal"
}
print("--- Instrumentos (Claves) ---")
for instrumento in instrumentos_clasificacion: # Itera sobre las claves por defecto
print(f"El instrumento es: {instrumento} (Clasificación: {instrumentos_clasificacion[instrumento]})")
# O explícitamente: for instrumento in instrumentos_clasificacion.keys():
.values()):# Puntos de fusión de metales (°C) - Química/Física
puntos_fusion_C = {"Aluminio": 660.3, "Hierro": 1538, "Cobre": 1084.6, "Plomo": 327.5}
print("\n--- Puntos de Fusión Registrados ---")
total_temp = 0
for temperatura in puntos_fusion_C.values():
print(f"- {temperatura}°C")
total_temp += temperatura
print(f"Suma de temperaturas (solo para ejemplo): {total_temp:.1f}°C")
.items()):Esta es la forma más común cuando necesitas tanto la clave como el valor.
# Catálogo de estrellas y sus constelaciones (Astronomía)
estrellas_constelaciones = {
"Sirio": "Can Mayor", "Betelgeuse": "Orión", "Polaris": "Osa Menor"
}
print("\n--- Estrellas y Constelaciones ---")
for estrella, constelacion in estrellas_constelaciones.items():
print(f"La estrella {estrella} se encuentra en la constelación de {constelacion}.")
Un diccionario anidado es un diccionario que contiene otros diccionarios como valores. Esto te permite modelar datos jerárquicos o entidades con múltiples atributos de forma muy natural. [cite: 198]
# Información de estudiantes (Educación/Ciencias Sociales)
registro_estudiantes = {
"ID001": {
"nombre": "Ana Pérez",
"edad": 16,
"cursos": ["Matemáticas", "Física", "Química"],
"promedio_general": 8.8
},
"ID002": {
"nombre": "Luis Gómez",
"edad": 17,
"cursos": ["Biología", "Historia", "Literatura"],
"promedio_general": 9.2,
"actividades_extra": {"club_ciencias": True, "deportes": "Fútbol"}
}
}
# Acceder a datos anidados
nombre_estudiante_1 = registro_estudiantes["ID001"]["nombre"]
curso_fisica_ana = "Física" in registro_estudiantes["ID001"]["cursos"]
club_luis = registro_estudiantes["ID002"]["actividades_extra"]["club_ciencias"]
print(f"Nombre del estudiante ID001: {nombre_estudiante_1}")
print(f"¿Ana cursa Física?: {curso_fisica_ana}")
print(f"¿Luis está en el club de ciencias?: {club_luis}")
# Modificar un dato anidado
registro_estudiantes["ID002"]["promedio_general"] = 9.3
print(f"Nuevo promedio de Luis: {registro_estudiantes['ID002']['promedio_general']}")
# Añadir un nuevo estudiante
registro_estudiantes["ID003"] = {
"nombre": "Sofía Castro", "edad": 16,
"cursos": ["Música", "Arte"], "promedio_general": 9.5
}
# Iterar y mostrar información clave
print("\n--- Resumen de Estudiantes ---")
for id_est, info in registro_estudiantes.items():
print(f"ID: {id_est}, Nombre: {info['nombre']}, Promedio: {info['promedio_general']}")
if "actividades_extra" in info and info["actividades_extra"].get("deportes"):
print(f" Deporte: {info['actividades_extra']['deportes']}")
🏛️ Organización Jerárquica: Los diccionarios anidados son la base para estructuras de datos como JSON (JavaScript Object Notation), muy comunes en APIs web y almacenamiento de datos. Poder manejarlos es una habilidad muy valiosa.
Python evoluciona, ¡y sus diccionarios también!
| (desde Python 3.9): Combina dos diccionarios para crear uno nuevo. Si hay claves repetidas, prevalece el valor del diccionario de la derecha. [cite: 98, 199]|= (desde Python 3.9): Actualiza un diccionario con los ítems de otro, modificando el diccionario original. [cite: 101, 200]# Ejemplo de orden (Python 3.7+)
config_experimento_pasos = {}
config_experimento_pasos["paso1_calibracion"] = {"duracion_min": 5, "instrumento": "Espectrómetro"}
config_experimento_pasos["paso2_medicion"] = {"temperatura_C": 22.5, "repeticiones": 3}
config_experimento_pasos["paso3_analisis"] = {"software": "Python_SciPy", "metodo": "Regresión Lineal"}
print("Pasos del experimento (ordenados por inserción):")
for paso, detalles in config_experimento_pasos.items():
print(f"- {paso}: {detalles}")
# Ejemplo de operadores de unión y actualización (Python 3.9+)
# Datos de un compuesto químico
propiedades_basicas_comp = {"formula": "NaCl", "estado": "Sólido"}
propiedades_fisicas_comp = {"punto_fusion_C": 801, "densidad_g_cm3": 2.17, "estado": "Sólido Cristalino"}
# Unión con | (crea un nuevo diccionario)
compuesto_completo = propiedades_basicas_comp | propiedades_fisicas_comp
print(f"\nCompuesto completo (unión |): {compuesto_completo}")
# La clave "estado" toma el valor de propiedades_fisicas_comp
# Actualización in-place con |=
propiedades_basicas_comp |= {"soluble_en_agua": True, "color": "Blanco"}
print(f"Propiedades básicas actualizadas (|=): {propiedades_basicas_comp}")
Al igual que las listas por comprensión, Python te permite crear diccionarios de una forma concisa y elegante usando la comprensión de diccionarios. La sintaxis es {clave_exp: valor_exp for item in iterable if condicion}. [cite: 73, 197]
# Crear un diccionario de números y sus cuadrados
numeros = [1, 2, 3, 4, 5]
cuadrados_dict = {n: n**2 for n in numeros}
print(f"Números y sus cuadrados: {cuadrados_dict}")
# Salida: {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
# Crear un diccionario con longitudes de palabras (Lingüística)
palabras_cientificas = ["átomo", "molécula", "energía", "célula", "gen"]
longitudes_palabras = {palabra: len(palabra) for palabra in palabras_cientificas}
print(f"Longitudes: {longitudes_palabras}")
# Filtrar y crear un diccionario de elementos y sus masas molares (Química)
masas_molares_todos = {"H": 1.008, "O": 15.999, "C": 12.011, "N": 14.007, "S": 32.06}
elementos_ligeros = {simbolo: masa for simbolo, masa in masas_molares_todos.items() if masa < 20}
print(f"Elementos ligeros (masa < 20): {elementos_ligeros}")
# Salida: {'H': 1.008, 'O': 15.999, 'C': 12.011, 'N': 14.007}
✨ Concisión y Legibilidad: Las comprensiones de diccionarios son una herramienta poderosa para crear diccionarios a partir de otros iterables de una manera muy expresiva, una vez que te familiarizas con su sintaxis.
¡Has completado una inmersión profunda en los diccionarios de Python! Estas estructuras de mapeo clave-valor son increíblemente poderosas y eficientes para organizar, buscar y gestionar información de manera estructurada.
Ahora puedes:
get() y setdefault().keys(), values(), items(), pop(), popitem(), y update().Los diccionarios son una herramienta fundamental en el arsenal de cualquier programador Python, y son especialmente cruciales en campos como el análisis de datos, la bioinformática, la física computacional, el desarrollo web y cualquier área donde se necesite gestionar información asociada y realizar búsquedas rápidas.
🚀 Desafío Científico-Musical:
Crea un diccionario para almacenar información sobre diferentes instrumentos musicales utilizados en una orquesta. Cada instrumento (clave, ej: "Violín") debe tener como valor otro diccionario con propiedades como: {"familia": "Cuerda frotada", "tesitura_aprox": ("G3", "E7"), "material_principal": "Madera"}.
Luego, escribe un código que: