Diccionarios y conjuntos

Enterate del próximo post
Un mail cuando publico algo nuevo. Sin spam y te podés dar de baja cuando quieras.

Un mail cuando publico algo nuevo. Sin spam y te podés dar de baja cuando quieras.
Una lista organiza valores por posición: el primero, el segundo, el tercero. Sirve bien cuando el orden importa y alcanza con contar desde el uno en adelante. Pero hay preguntas que una lista responde mal. Una agenda de contactos no se recorre posición por posición para encontrar el teléfono de una persona: se busca directamente por el nombre. Y una lista de invitados a un evento no necesita ningún orden ni admite que el mismo nombre aparezca dos veces: solo hace falta saber si una persona está invitada o no.
Esas dos preguntas -qué valor le corresponde a un nombre, y si un valor está presente o no- dan lugar a dos estructuras nuevas.
Un diccionario es una colección que asocia cada valor a una clave, en vez de a una posición. La clave reemplaza al número de posición de una lista: en vez de pedir el elemento en la posición 3, se pide el valor asociado a una clave. El orden en el que se agregaron los pares no importa, y cada clave aparece una sola vez: si se vuelve a escribir la misma clave, se reemplaza el valor anterior, no se agrega un segundo par.
Un conjunto es una colección sin orden y sin valores repetidos. No asocia nada a nada: cada valor está presente o no está, y esa es toda la información que guarda. Agregar un valor que ya estaba no cambia nada, porque el conjunto ya lo tenía.
Un diccionario se escribe entre llaves, cada par como clave y valor separados por dos puntos, y los pares separados por coma: {"pan": 800, "leche": 950}. El diccionario vacío se escribe {}. Cuatro operaciones:
el valor asociado a la clave K en diccionario.asignar valor a la clave K en diccionario (misma idea que asignar a una posición de una lista, solo que en vez de un número se usa una clave).diccionario contiene la clave K.quitar la clave K de diccionario.Y para contar: la cantidad de claves de diccionario.
Un conjunto se escribe entre llaves, los valores separados por coma, sin ningún dos puntos: {"Marcos", "Julieta", "Sol"}. Como las llaves vacías ya nombran al diccionario vacío, cuando el contexto no lo deja claro se aclara con una palabra: "el conjunto vacío". Cuatro operaciones, con la misma forma que las del diccionario:
agregar valor a conjunto (si el valor ya estaba, no pasa nada nuevo).conjunto contiene valor.quitar valor de conjunto.la cantidad de elementos de conjunto.Elegir entre lista, diccionario y conjunto no es una cuestión de gusto: depende de cuál de esas preguntas hace falta responder más seguido sobre esos datos.
El primer ejemplo busca un teléfono por nombre en una agenda:
algoritmo telefono_de(agenda, nombre):
devolver el valor asociado a la clave nombre en agendaCon agenda = {"Marcos": "1122334455", "Julieta": "1166778899", "Sol": "1145678900"}:
telefono_de(agenda, "Julieta") devuelve "1166778899".telefono_de(agenda, "Sol") devuelve "1145678900".No hace falta recorrer nada ni comparar cada nombre uno por uno: la clave lleva directo al valor que le corresponde.
El segundo ejemplo pregunta si una persona está invitada, usando un conjunto:
algoritmo hay_invitado(invitados, nombre):
devolver invitados contiene nombreCon invitados = {"Marcos", "Julieta", "Sol"}:
hay_invitado(invitados, "Sol") devuelve verdadero.hay_invitado(invitados, "Bruno") devuelve falso.El conjunto no guarda ningún teléfono ni ningún otro dato sobre cada persona: solo responde presencia. Si además hiciera falta el teléfono de cada invitado, la herramienta correcta sería un diccionario, no un conjunto.
Un sistema guarda el precio de cada producto en un diccionario, donde la clave es el nombre del producto y el valor es su precio actual. Escribir un algoritmo actualizar_precio que reciba ese diccionario, el nombre de un producto y un precio nuevo, y deje ese precio actualizado, sin importar si el producto ya tenía un precio guardado o es la primera vez que aparece. Usar un diccionario.
Pista: pensar qué operación permite escribir en una clave sin necesitar antes ninguna decisión sobre si esa clave ya existía o no.
algoritmo actualizar_precio(precios, nombre, precio_nuevo):
asignar precio_nuevo a la clave nombre en precios
devolver preciosCon precios = {"pan": 800, "leche": 950}:
actualizar_precio(precios, "leche", 1000) deja precios en {"pan": 800, "leche": 1000}.actualizar_precio(precios, "arroz", 700) deja precios en {"pan": 800, "leche": 1000, "arroz": 700}.La misma operación -asignar a una clave- sirve tanto para reemplazar un valor existente como para agregar uno nuevo, sin ninguna decisión de por medio. Es una diferencia real con una lista, donde reemplazar un elemento existente y agregar uno nuevo son dos operaciones distintas: asignar valor al elemento en la posición N de lista no es lo mismo que agregar valor al final de lista.
Un comercio registra las compras de sus clientes para acumular puntos. Guarda dos cosas: qué clientes ya están registrados, y cuántos puntos tiene cada uno acumulados hasta ahora. Cuando compra un cliente nuevo, hay que darlo de alta y arrancar su acumulado con los puntos que ganó en esa primera compra. Cuando compra un cliente que ya estaba registrado, alcanza con sumarle los puntos nuevos a los que ya tenía.
Pista: antes de decidir qué hacer con los puntos, hace falta saber si el cliente ya estaba registrado o no.
algoritmo registrar_compra(clientes, puntos, id_cliente, puntos_nuevos):
si clientes no contiene id_cliente:
agregar id_cliente a clientes
asignar puntos_nuevos a la clave id_cliente en puntos
sino:
sumar puntos_nuevos al valor asociado a la clave id_cliente en puntos
devolver puntosCon clientes = {"C001", "C002"} y puntos = {"C001": 120, "C002": 340}:
registrar_compra(clientes, puntos, "C002", 50): "C002" ya está en clientes, así que se suman los 50 puntos nuevos a los 340 que ya tenía. puntos queda en {"C001": 120, "C002": 390}.registrar_compra(clientes, puntos, "C003", 80): "C003" no estaba en clientes, así que se agrega ahí y se le asigna directamente 80 en puntos. clientes queda en {"C001", "C002", "C003"} y puntos en {"C001": 120, "C002": 390, "C003": 80}.El conjunto responde si el cliente es nuevo. El diccionario guarda cuánto acumuló. Ninguna de las dos estructuras podría resolver esto sola.
Una lista responde qué hay en la posición N. Un diccionario responde qué valor tiene una clave. Un conjunto responde si un valor está o no. Elegir la estructura correcta es elegir, antes que nada, cuál de esas tres preguntas hace falta responder.
El próximo post presenta otras dos estructuras de la misma familia, pensadas no para buscar por clave sino para controlar el orden exacto en que los datos entran y salen.