1.7 · Diccionarios y conjuntos¶
Objetivos. Al terminar este capítulo podrás: modelar datos con diccionarios (clave→valor), modificarlos y recorrerlos; y usar conjuntos para operar con elementos únicos.
Evidencia de logro. Construirás un contador de palabras y una agenda de
contactos, eligiendo entre dict, set y las otras estructuras según el
problema.
Contexto y motivación¶
Las listas conservan los elementos en un orden, pero a menudo necesitas buscar
un dato mediante un identificador, como el teléfono de una persona o el precio
de un producto. El diccionario representa precisamente esa relación entre
una clave y un valor. En otros casos solo necesitas conservar elementos únicos,
como los clientes que han comprado o las categorías disponibles; para eso está
el set.
En una aplicación de IA, los diccionarios pueden representar un registro de cliente, los parámetros de un modelo, una petición HTTP o el JSON de una API. Aprender a elegirlos y recorrerlos facilita el trabajo con esos datos.
Vocabulario¶
| Término | Significado |
|---|---|
Diccionario (dict) |
Colección clave → valor ({clave: valor}) |
| Clave | Identificador único del valor (debe ser inmutable) |
| Valor | Lo que se guarda (puede ser de cualquier tipo) |
Conjunto (set) |
Colección de elementos únicos y sin orden ({...}) |
| Clave hashable | str, int, float o una tuple cuyos elementos también sean hashables; las listas no sirven |
Prerrequisitos¶
1.6 · Listas y tuplas (mutabilidad, tuplas, iterables).
Ruta de estudio
El núcleo obligatorio es crear, consultar, modificar y recorrer
diccionarios, usar get, representar datos anidados y aplicar las
operaciones básicas de conjuntos. Las comprensiones, la ordenación por
valor y los métodos menos frecuentes se trabajan como ampliación después
de elegir correctamente la estructura.
1. Crear y acceder a diccionarios¶
cliente = {"nombre": "Ana", "edad": 20, "ciudad": "Sevilla"}
print(cliente["nombre"]) # acceso por clave
print(cliente.get("pais", "Desconocido")) # seguro, con valor por defecto
Salida esperada:
Un diccionario se escribe entre llaves {} con pares clave: valor separados
por comas. cliente["nombre"] devuelve el valor asociado a esa clave; si la
clave no existe, Python se detiene con KeyError.
cliente.get(clave, por_defecto) devuelve por_defecto si no existe: permite
consultar una clave sin que el programa falle.
Salida esperada (error):
2. Modificar diccionarios¶
persona = {"nombre": "Ana"}
persona["edad"] = 20 # añadir una clave nueva
persona["nombre"] = "María" # modificar una existente
del persona["edad"] # borrar una clave
print(persona)
Salida esperada:
Asignar persona[clave] = valor añade la clave si no existe y modifica
su valor si ya existe: un diccionario no puede tener dos claves iguales. del
elimina la clave y su valor.
3. Métodos y vistas¶
stock = {"lapiz": 10, "goma": 4}
print(list(stock.keys())) # claves
print(list(stock.values())) # valores
print(list(stock.items())) # pares (clave, valor)
print(stock.get("lapiz"), stock.get("regla", 0))
Salida esperada:
keys(), values() e items() son vistas que se pueden recorrer o pasar a
list(). items() devuelve tuplas (clave, valor), ideal para recorrer. Desde
Python 3.7, un diccionario conserva el orden en que insertaste las claves:
por eso lapiz sale antes que goma.
4. Recorrer un diccionario¶
Salida esperada:
En cada vuelta, items() entrega una tupla (clave, valor) y el
desempaquetado de 1.6 la reparte en producto y unidades. Puedes recorrer
solo stock.keys(), solo stock.values(), o ambos con items(). Si recorres el
diccionario directamente (for producto in stock:), obtienes solo las claves.
5. Diccionarios anidados¶
Un valor puede ser otro diccionario (o una lista):
usuarios = {
"u1": {"nombre": "Ana", "edad": 20},
"u2": {"nombre": "Luis", "edad": 25},
}
print(usuarios["u1"]["nombre"])
Salida esperada:
Es la estructura típica de un JSON o de datos jerárquicos (un usuario con sus
atributos). Para acceder, encadenas claves: usuarios["u1"]["nombre"].
6. Ampliación: comprehension de diccionarios¶
Igual que las listas, pero con clave: valor:
Salida esperada:
Útil para construir un diccionario a partir de otra colección: {p: len(p) for
p in ["a", "bb"]} → {'a': 1, 'bb': 2}.
7. Ampliación: ordenar, máximo y mínimo (y otros métodos útiles)¶
A diferencia de las listas, un dict no tiene .sort(). Para ordenarlo lo
conviertes en una lista de pares con sorted():
edades = {"Ana": 20, "Luis": 25, "Marta": 18}
print(sorted(edades)) # claves ordenadas
print(sorted(edades.items())) # pares, ordenados por clave
Salida esperada:
sorted(edades) ordena las claves; sorted(edades.items()) devuelve los pares
ordenados por clave. Pero a menudo quieres ordenar por el valor (ej. "top de
ventas"):
print(sorted(edades.items(), key=lambda x: x[1])) # asc por valor
print(sorted(edades.items(), key=lambda x: x[1], reverse=True)) # desc
print(sorted(edades.items(), key=lambda x: x[1], reverse=True)[:2]) # top 2
Salida esperada:
[('Marta', 18), ('Ana', 20), ('Luis', 25)]
[('Luis', 25), ('Ana', 20), ('Marta', 18)]
[('Luis', 25), ('Ana', 20)]
El argumento key=lambda x: x[1] dice "ordena por el segundo elemento de
cada pareja (el valor)". [:2] se queda con los 2 primeros → el "top 2".
También puedes pedir el máximo/mínimo por clave o por valor:
print(max(edades, key=edades.get)) # la clave con el mayor valor -> Luis
print(min(edades, key=edades.get)) # la clave con el menor valor -> Marta
print(max(edades.values())) # el mayor valor -> 25
Salida esperada:
max(edades, key=edades.get) recorre las claves y compara el resultado de
edades.get(clave) para cada una; devuelve la clave cuyo valor es mayor. Fíjate
en que edades.get va sin paréntesis: no se llama aquí, se le entrega a
max para que la llame con cada clave. max(edades.values()) devuelve el mayor
valor directamente. Es el patrón para "¿quién tiene más/la mayor cifra?".
7.1 Otros métodos que conviene conocer¶
grupo = {"Ana": 20}
print("Luis" in grupo) # ¿existe la clave?
print(grupo.get("Sara", 0)) # seguro, con valor por defecto
grupo.update({"Luis": 25}) # añade/actualiza varias claves
grupo["Sara"] = 30
print(grupo.pop("Ana")) # saca y devuelve el valor de una clave
print(grupo)
Salida esperada:
Útiles que verás a menudo: update(otro) fusiona, pop(clave) extrae y
borra, setdefault(clave, valor) añade solo si no existe, copy() hace una
copia independiente y clear() vacía el diccionario. Fíjate en que in
comprueba las claves, no los valores.
8. Conjuntos (set)¶
Un set guarda elementos únicos y sin orden:
numeros = {1, 2, 2, 3}
print(sorted(numeros))
vacio = set() # conjunto vacío: {} crearía un diccionario vacío
print(type(vacio), type({}))
Salida esperada:
El duplicado 2 desaparece. Un set responde rápido a "¿está este elemento?".
Usamos sorted solo para mostrar una salida estable; el conjunto sigue sin
tener orden. Y cuidado con el conjunto vacío: {} es un diccionario vacío;
para un conjunto vacío hay que escribir set().
Los set no tienen orden
El orden de un set no está garantizado. Si te importa el orden, usa una
lista o un conjunto ordenado (con sorted). No confíes en que los elementos
salgan en el orden en que los metiste.
9. Operaciones con conjuntos¶
a = {1, 2, 3}
b = {2, 3, 4}
print(sorted(a & b)) # intersección: comunes
print(sorted(a | b)) # unión: todos
print(sorted(a - b)) # diferencia: solo en a
print(sorted(a ^ b)) # diferencia simétrica: en uno u otro, no ambos
Salida esperada:
Estas operaciones responden a preguntas de negocio: ¿qué clientes compraron
ambos días (&)? ¿cuáles solo hoy (-)? En Python se escriben con símbolos y
son muy rápidas.
10. Aplicación práctica: contador de palabras¶
texto = "hola mundo hola"
palabras = texto.split() # divide el texto por los espacios
frecuencia = {}
for palabra in palabras:
frecuencia[palabra] = frecuencia.get(palabra, 0) + 1
print(frecuencia)
Salida esperada:
texto.split() divide una cadena por los espacios y devuelve la lista
['hola', 'mundo', 'hola'] (lo verás en 1.9 · Cadenas).
Después, el patrón frecuencia.get(palabra, 0) + 1 es la forma clásica de
contar: si la palabra ya estaba, suma 1 a su cuenta; si no, parte de 0 y suma 1.
Lo verás constantemente (contar apariciones, frecuencias, votos).
11. ¿Cuándo usar cada estructura?¶
| Necesitas | Estructura |
|---|---|
| Elementos en orden, que pueden repetirse | lista |
| Buscar por clave (nombre→valor) | diccionario |
| Elementos únicos y comprobar pertenencia | conjunto |
| Datos fijos que van juntos | tupla |
Regla: si buscas por nombre, dict; si solo quieres unicidad, set; si
es una lista ordenada, list.
Errores frecuentes¶
- Usar
d["clave"]cuando la clave puede no existir (daKeyError); usad.get(clave, default). - Intentar usar una lista como clave de un
dict(no es inmutable); usa una tupla. - Recorrer un
dictconfor k in d:y usard[k]cuando puedes hacerfor k, v in d.items():. - Creer que un
setmantiene el orden de inserción. - Escribir
{}para crear un conjunto vacío: es un diccionario; usaset(). - Confundir
dict(clave→valor) conset(elementos únicos).
Práctica de transferencia¶
- Crea un
dictcon 3 productos (nombre → precio) y muestra el precio de uno conget()(con un valor por defecto para uno inexistente). - A partir de
texto = "la casa es casa grande y la luz es luz", cuenta la frecuencia de cada palabra. - Con dos
setde clientes que compraron el lunes y el martes, muestra quiénes compraron ambos días y quiénes solo el lunes. - Convierte la lista
[1, 2, 2, 3, 3, 3]en unsety explica qué pasa con los duplicados. - Crea una agenda: un diccionario cuyas claves sean nombres y cuyos
valores sean diccionarios con
telefonoyemail. Muestra el email de una persona y usagetpara que buscar a alguien que no está no rompa el programa.
Qué debes justificar: en cada ejercicio, por qué la estructura elegida (dict,
set o lista) es la adecuada para esa pregunta.
Producto evaluable¶
Segunda versión del cuaderno 05_colecciones.py, recibido en 1.6 y ampliado
ahora con:
- El contador de palabras y la agenda de contactos (un
dictanidado con teléfonos/emails), cada uno con su interpretación. - Una celda con las operaciones de
set(intersección, unión, diferencia) y su lectura en lenguaje natural. - Una celda final que compare lista, tupla, dict y set en una tabla, con un ejemplo donde cada una tiene sentido.
Formato de entrega: cuaderno marimo ejecutado, con salida esperada, interpretación y conclusión.
Resumen y referencia rápida¶
| Estructura | Sintaxis | Para qué |
|---|---|---|
| Lista | [1,2,3] |
Orden, repetición, mutabilidad |
| Tupla | (1,2,3) |
Datos fijos, claves de dict |
| Diccionario | {"a": 1} |
Clave → valor, búsqueda rápida |
| Conjunto | {1,2,3} |
Elementos únicos, pertenencia |
Métodos clave de dict: get, keys, values, items. Operadores de set:
&, |, -, ^. Para ordenar: sorted(d.items(), key=lambda x: x[1]); para
el extremo por valor: max(d, key=d.get).
Siguiente: 1.8 · Funciones.