# ─────────────────────────────────────────────
# DICCIONARIOS EN PYTHON
# ─────────────────────────────────────────────
# Un diccionario guarda pares clave: valor
# · Las claves son únicas (no puede haber dos iguales)
# · Los valores pueden ser de cualquier tipo
# · Se definen con llaves { }
# · A diferencia de las listas, NO se accede por posición
# sino por el nombre de la clave
producto = {
'referencia': 'SK789',
'precio': 200
}
print(producto) # → {'referencia': 'SK789', 'precio': 200}
clase = {'nombre': 'WEB', 'capacidad': 20}
print(clase) # → {'nombre': 'WEB', 'capacidad': 20}
# ─────────────────────────────────────────────
# LEER Y MODIFICAR VALORES
# ─────────────────────────────────────────────
# Acceder a un valor con su clave entre corchetes
print(clase['nombre']) # → WEB
print(clase['capacidad']) # → 20
# Modificar un valor existente (misma sintaxis que al leer)
clase['capacidad'] = 15
print(clase) # → {'nombre': 'WEB', 'capacidad': 15}
camisa = {
'talla': 'L',
'color': 'rojo',
'precio': 20,
'moneda': '€'
}
# f-string con acceso al diccionario dentro de las llaves { }
print(f"La talla de la camisa es {camisa['talla']}") # → La talla de la camisa es L
# ─────────────────────────────────────────────
# ACCESO SEGURO: get()
# ─────────────────────────────────────────────
# Si accedemos a una clave que NO existe con corchetes → ERROR (KeyError)
# print(camisa['stock']) ← esto lanzaría un KeyError y detendría el programa
# get(clave) devuelve el valor si existe, o None si no existe (sin error)
print(camisa.get('stock')) # → None
# get(clave, valor_por_defecto) devuelve el valor por defecto si no existe
print(camisa.get('stock', 0)) # → 0 ← mucho más útil en la práctica
# 💡 ALTERNATIVA: comprobar antes con 'in'
if 'stock' in camisa:
print(camisa['stock'])
else:
print("La clave 'stock' no existe")
# ─────────────────────────────────────────────
# AÑADIR CLAVES NUEVAS
# ─────────────────────────────────────────────
# Asignar a una clave que no existe → la crea automáticamente
camisa['stock'] = 20
print(camisa)
# → {'talla':'L','color':'rojo','precio':20,'moneda':'€','stock':20}
# ─────────────────────────────────────────────
# UPDATE: añadir o modificar varias claves a la vez
# ─────────────────────────────────────────────
# update() acepta argumentos con nombre (clave=valor)
camisa.update(almacen='Central', activo=True)
print(camisa)
# → {..., 'almacen': 'Central', 'activo': True}
# 💡 ALTERNATIVA: pasarle otro diccionario
# camisa.update({'almacen': 'Central', 'activo': True})
# 💡 ALTERNATIVA desde Python 3.9: operador |=
# camisa |= {'almacen': 'Central', 'activo': True}
# ─────────────────────────────────────────────
# VISTAS: keys(), values(), items()
# ─────────────────────────────────────────────
# Estas tres funciones devuelven "vistas" del diccionario.
# No son listas normales, pero se pueden recorrer con for
# y se actualizan automáticamente si el diccionario cambia.
claves = camisa.keys() # Todas las claves
valores = camisa.values() # Todos los valores
elementos = camisa.items() # Pares (clave, valor) como tuplas
print(claves) # → dict_keys(['talla', 'color', 'precio', ...])
print(valores) # → dict_values(['L', 'rojo', 20, ...])
print(elementos) # → dict_items([('talla','L'), ('color','rojo'), ...])
# 💡 Si necesitas una lista real puedes convertirlas:
# list(camisa.keys()) → ['talla', 'color', 'precio', ...]
# list(camisa.values()) → ['L', 'rojo', 20, ...]
# ─────────────────────────────────────────────
# ACCEDER CON UNA VARIABLE COMO CLAVE
# ─────────────────────────────────────────────
# La clave puede estar guardada en una variable, no tiene que ser literal
miclave = "stock"
print(camisa[miclave]) # → 20
miclave = "almacen"
print(camisa[miclave]) # → Central
# Esto es muy útil cuando la clave viene de una entrada del usuario
# o se calcula en tiempo de ejecución
# ─────────────────────────────────────────────
# RECORRER UN DICCIONARIO CON FOR
# ─────────────────────────────────────────────
# OPCIÓN 1: iterar solo por las claves y acceder al valor manualmente
for clave in camisa.keys():
print(clave, camisa[clave])
# OPCIÓN 2 (más elegante): iterar por clave y valor a la vez con items()
for clave, valor in camisa.items():
print(clave, valor)
# 💡 ALTERNATIVA: iterar directamente (sin .keys()) hace lo mismo que la opción 1
# for clave in camisa:
# print(clave, camisa[clave])
# 💡 ALTERNATIVA: crear una lista de pares formateados con comprensión de lista
# pares = [f"{k} → {v}" for k, v in camisa.items()]
# ─────────────────────────────────────────────
# ELIMINAR ELEMENTOS: pop() y popitem()
# ─────────────────────────────────────────────
# pop(clave): elimina la clave indicada y DEVUELVE su valor
elemento = camisa.pop('almacen')
print(elemento) # → Central (el valor que tenía 'almacen')
print(camisa) # → {...} sin 'almacen'
# 💡 pop() también acepta valor por defecto para evitar errores:
# camisa.pop('clave_inexistente', None) → devuelve None sin error
# popitem(): elimina y devuelve el ÚLTIMO par (clave, valor) insertado
# Devuelve una tupla → ('clave', valor)
elemento = camisa.popitem()
print(elemento) # → ('activo', True) (el último que se añadió)
print(camisa) # → {...} sin 'activo'
# 💡 ALTERNATIVA para eliminar sin recuperar el valor:
# del camisa['precio'] → borra la clave directamente