Diccionarios: pares clave-valor
Introducción
Los diccionarios son una de las estructuras de datos más versátiles y útiles en Python. A diferencia de las listas y tuplas, que almacenan elementos en secuencia ordenada accesibles por índices numéricos, los diccionarios nos permiten organizar datos mediante pares de clave-valor. Esta estructura facilita enormemente la búsqueda y recuperación de información específica cuando conocemos su identificador o clave. Los diccionarios son fundamentales para el manejo eficiente de datos en Python y encontraremos su uso en prácticamente cualquier programa que maneje conjuntos complejos de información.
Definición y creación de diccionarios
Un diccionario en Python es una colección desordenada (aunque desde Python 3.7 mantienen el orden de inserción) de pares clave-valor, donde cada clave debe ser única e inmutable. Las claves actúan como identificadores para acceder a los valores almacenados.
Hay varias formas de crear un diccionario:
# Método 1: Usando llaves {} con pares clave-valor
estudiante = {
"nombre": "Laura",
"apellido": "Sánchez",
"edad": 22,
"asignaturas": ["Matemáticas", "Física", "Programación"]
}
print(estudiante)
# Método 2: Usando el constructor dict()
colores = dict(rojo="#FF0000", verde="#00FF00", azul="#0000FF")
print(colores)
# Método 3: A partir de secuencias de pares
ciudades = dict([("Madrid", "España"), ("París", "Francia"), ("Roma", "Italia")])
print(ciudades)
# Método 4: Diccionario vacío
mi_diccionario = {}
print(type(mi_diccionario)) # Salida: <class 'dict'>
Acceso a los valores
Para acceder a un valor en un diccionario, utilizamos su clave correspondiente:
usuario = {
"id": 1234,
"nombre": "Carlos",
"email": "carlos@ejemplo.com",
"activo": True
}
# Acceso básico
print(usuario["nombre"]) # Salida: Carlos
print(usuario["email"]) # Salida: carlos@ejemplo.com
# Si intentamos acceder a una clave que no existe, obtendremos un error KeyError
try:
print(usuario["telefono"])
except KeyError as e:
print(f"Error: {e}") # Salida: Error: 'telefono'
# Método get() - permite proporcionar un valor predeterminado si la clave no existe
print(usuario.get("email", "No disponible")) # Salida: carlos@ejemplo.com
print(usuario.get("telefono", "No disponible")) # Salida: No disponible
Modificación de diccionarios
Los diccionarios son estructuras mutables, lo que significa que podemos añadir, modificar o eliminar elementos:
producto = {
"nombre": "Portátil",
"precio": 799.99,
"disponible": True
}
# Modificar un valor existente
producto["precio"] = 749.99
print(producto) # El precio ha sido actualizado
# Añadir un nuevo par clave-valor
producto["marca"] = "TechPro"
print(producto) # Ahora incluye la marca
# Eliminar un par clave-valor con del
del producto["disponible"]
print(producto) # Ya no incluye 'disponible'
# Eliminar un par con pop() (devuelve el valor eliminado)
marca = producto.pop("marca")
print(f"Marca eliminada: {marca}")
print(producto) # Ya no incluye 'marca'
# Eliminar y obtener el último par insertado con popitem() (desde Python 3.7)
ultimo_par = producto.popitem()
print(f"Último par eliminado: {ultimo_par}")
print(producto)
# Vaciar el diccionario
producto.clear()
print(producto) # Salida: {}
Métodos comunes de diccionarios
Python proporciona varios métodos útiles para trabajar con diccionarios:
inventario = {
"mesa": 15,
"silla": 45,
"lámpara": 20,
"estantería": 8
}
# keys() - Devuelve un objeto vista con todas las claves
print(list(inventario.keys())) # Convertimos a lista para imprimir
# values() - Devuelve un objeto vista con todos los valores
print(list(inventario.values()))
# items() - Devuelve un objeto vista con todos los pares clave-valor como tuplas
print(list(inventario.items()))
# update() - Actualiza un diccionario con los pares de otro
nuevos_items = {"sofá": 5, "mesa": 20} # 'mesa' se actualizará
inventario.update(nuevos_items)
print(inventario)
# setdefault() - Inserta un par clave-valor si la clave no existe
inventario.setdefault("alfombra", 12) # Se añade porque no existe
inventario.setdefault("silla", 50) # No se modifica porque ya existe
print(inventario)
# fromkeys() - Crea un nuevo diccionario con las claves especificadas y el mismo valor
productos = ["laptop", "tablet", "móvil"]
precios_iniciales = dict.fromkeys(productos, 0)
print(precios_iniciales)
Iteración sobre diccionarios
Hay varias formas de recorrer un diccionario:
puntuaciones = {
"Ana": 95,
"Luis": 88,
"Carmen": 92,
"Pedro": 78
}
# Iteración sobre las claves (comportamiento predeterminado)
print("Estudiantes:")
for estudiante in puntuaciones:
print(estudiante)
# Iteración sobre los valores
print("\nPuntuaciones:")
for puntuacion in puntuaciones.values():
print(puntuacion)
# Iteración sobre pares clave-valor
print("\nEstudiantes y puntuaciones:")
for estudiante, puntuacion in puntuaciones.items():
print(f"{estudiante}: {puntuacion}")
# Encontrar la puntuación máxima
mejor_estudiante = max(puntuaciones, key=puntuaciones.get)
print(f"\nMejor estudiante: {mejor_estudiante} con {puntuaciones[mejor_estudiante]} puntos")
Diccionarios anidados
Los diccionarios pueden contener otros diccionarios como valores, lo que permite estructuras de datos más complejas:
empleados = {
"E001": {
"nombre": "María",
"departamento": "Ventas",
"salario": 2500,
"contacto": {
"email": "maria@empresa.com",
"telefono": "666-555-444"
}
},
"E002": {
"nombre": "Juan",
"departamento": "IT",
"salario": 2800,
"contacto": {
"email": "juan@empresa.com",
"telefono": "666-777-888"
}
}
}
# Acceso a datos anidados
print(empleados["E001"]["nombre"]) # Salida: María
print(empleados["E002"]["contacto"]["email"]) # Salida: juan@empresa.com
# Modificación de datos anidados
empleados["E001"]["salario"] = 2700
print(empleados["E001"]["salario"]) # Salida: 2700
# Añadir un nuevo nivel
empleados["E001"]["historial"] = {"2023": "Excelente", "2022": "Bueno"}
print(empleados["E001"]["historial"]["2023"]) # Salida: Excelente
Comprensión de diccionarios
Similar a la comprensión de listas, Python permite crear diccionarios de forma concisa mediante la comprensión de diccionarios:
# Lista de números
numeros = [1, 2, 3, 4, 5]
# Crear un diccionario donde las claves son los números y los valores son sus cuadrados
cuadrados = {n: n**2 for n in numeros}
print(cuadrados) # Salida: {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
# Comprensión con condición
pares_cuadrados = {n: n**2 for n in numeros if n % 2 == 0}
print(pares_cuadrados) # Salida: {2: 4, 4: 16}
# Convertir dos listas en un diccionario
frutas = ["manzana", "plátano", "naranja", "uva"]
precios = [1.2, 0.9, 1.5, 2.3]
frutas_precios = {fruta: precio for fruta, precio in zip(frutas, precios)}
print(frutas_precios)
Restricciones en las claves de un diccionario
Es importante destacar que las claves de un diccionario deben ser inmutables. Esto significa que podemos usar:
- Números (enteros, flotantes, complejos)
- Cadenas de texto
- Tuplas (siempre que contengan solo elementos inmutables)
- Frozensets
Pero no podemos usar:
- Listas
- Diccionarios
- Sets normales
# Claves válidas
diccionario_valido = {
100: "cien",
"clave": "valor",
(1, 2): "tupla como clave",
frozenset([1, 2, 3]): "conjunto inmutable como clave"
}
# Claves inválidas generarán error
try:
diccionario_invalido = {[1, 2, 3]: "esto causará error"}
except TypeError as e:
print(f"Error: {e}") # Salida: Error: unhashable type: 'list'
Casos de uso comunes de diccionarios
Los diccionarios son extremadamente útiles en muchos escenarios:
1. Contadores
# Contar ocurrencias de palabras en un texto
texto = "el perro persigue al gato y el gato corre asustado porque el perro ladra"
palabras = texto.split()
contador = {}
for palabra in palabras:
contador[palabra] = contador.get(palabra, 0) + 1
print(contador)
2. Mapeo de valores
# Traducción de palabras
traductor = {
"casa": "house",
"perro": "dog",
"gato": "cat",
"libro": "book"
}
frase = ["el", "perro", "y", "el", "gato", "están", "en", "casa"]
traduccion = [traductor.get(palabra, palabra) for palabra in frase]
print(" ".join(traduccion))
3. Caché o memorización
# Memorización de resultados de fibonacci
def fibonacci_con_memo():
memo = {0: 0, 1: 1} # Casos base
def fib(n):
if n not in memo:
memo[n] = fib(n-1) + fib(n-2)
return memo[n]
return fib
calcular_fib = fibonacci_con_memo()
print(calcular_fib(10)) # Salida: 55
4. Representación de objetos
# Representación de un blog post
post = {
"id": 1,
"titulo": "Introducción a Python",
"autor": {
"nombre": "Ana",
"email": "ana@blog.com"
},
"contenido": "Python es un lenguaje...",
"comentarios": [
{"usuario": "Luis", "texto": "¡Gran artículo!"},
{"usuario": "Elena", "texto": "Muy útil, gracias."}
],
"tags": ["python", "programación", "tutorial"]
}
# Podemos acceder fácilmente a cualquier información
print(f"Título: {post['titulo']}")
print(f"Autor: {post['autor']['nombre']}")
print(f"Primer comentario: {post['comentarios'][0]['texto']}")
Conversión entre diccionarios y otras estructuras
Los diccionarios pueden convertirse a y desde otras estructuras de datos:
# Lista de tuplas a diccionario
items = [("a", 1), ("b", 2), ("c", 3)]
dict_desde_items = dict(items)
print(dict_desde_items) # Salida: {'a': 1, 'b': 2, 'c': 3}
# Diccionario a lista de tuplas
items_desde_dict = list(dict_desde_items.items())
print(items_desde_dict) # Salida: [('a', 1), ('b', 2), ('c', 3)]
# Listas separadas de claves y valores
claves = ["nombre", "edad", "ciudad"]
valores = ["Miguel", 30, "Barcelona"]
# Combinamos con zip
persona = dict(zip(claves, valores))
print(persona) # Salida: {'nombre': 'Miguel', 'edad': 30, 'ciudad': 'Barcelona'}
Resumen
Los diccionarios son estructuras de datos fundamentales en Python que permiten almacenar información como pares clave-valor, ofreciendo un acceso eficiente a los datos mediante identificadores únicos. Su capacidad para modificarse, contener diversos tipos de datos (incluso otros diccionarios) y ofrecer métodos potentes para manipular la información los convierte en herramientas esenciales para el desarrollo de aplicaciones. A diferencia de las listas que están optimizadas para secuencias ordenadas, los diccionarios destacan en situaciones donde necesitamos buscar, actualizar o almacenar datos asociativos. En el próximo artículo exploraremos los conjuntos (sets), otra estructura de datos importante que nos permitirá trabajar con colecciones de elementos únicos y realizar operaciones matemáticas de conjuntos.