Métodos de dict: keys, values, items, get, setdefault y más
Los diccionarios de Python son estructuras de datos de primera clase. Más allá de acceder por clave, tienen métodos que hacen que el código sea expresivo y seguro.
keys(), values(), items()
Estos tres métodos devuelven vistas del diccionario. Una vista es un objeto dinámico — si el dict cambia, la vista refleja el cambio sin necesidad de recalcular.
persona = {
"nombre": "Ana",
"edad": 30,
"ciudad": "Madrid",
"profesion": "desarrolladora",
}
# keys() — todas las claves
print(list(persona.keys()))
# ['nombre', 'edad', 'ciudad', 'profesion']
# values() — todos los valores
print(list(persona.values()))
# ['Ana', 30, 'Madrid', 'desarrolladora']
# items() — pares (clave, valor) como tuplas
for clave, valor in persona.items():
print(f"{clave}: {valor}")
# Las vistas se comportan como sets para operaciones de conjuntos
config_a = {"host": "localhost", "port": 5432, "debug": True}
config_b = {"host": "prod.server", "port": 5432, "timeout": 30}
claves_comunes = config_a.keys() & config_b.keys()
print(claves_comunes) # {'host', 'port'}['nombre', 'edad', 'ciudad', 'profesion']
['Ana', 30, 'Madrid', 'desarrolladora']
nombre: Ana
edad: 30
ciudad: Madrid
profesion: desarrolladora
{'host', 'port'}get() con valor por defecto
dict[clave] lanza KeyError si la clave no existe. dict.get(clave, defecto) retorna el valor por defecto en su lugar — sin excepción. Es la forma segura de acceder a valores opcionales.
config = {"host": "localhost", "port": 5432}
# Acceso directo — lanza KeyError si la clave no existe
# print(config["debug"]) # KeyError: 'debug'
# get() con valor por defecto — seguro
host = config.get("host", "127.0.0.1")
debug = config.get("debug", False)
timeout = config.get("timeout", 30)
print(host) # localhost
print(debug) # False
print(timeout) # 30
# get() retorna None por defecto si no se especifica valor
usuario = config.get("usuario")
print(usuario) # None
# Caso práctico: contar frecuencias manualmente
texto = "python es genial"
frecuencia: dict[str, int] = {}
for letra in texto:
frecuencia[letra] = frecuencia.get(letra, 0) + 1
print(dict(sorted(frecuencia.items())))localhost
False
30
None
{' ': 2, 'a': 1, 'e': 2, 'g': 1, 'h': 1, 'i': 1, 'l': 1, 'n': 3, 'o': 1, 'p': 1, 's': 1, 't': 1, 'y': 1}| Acceso directo | get() seguro |
|---|---|
| d['key'] # KeyError si no existe | d.get('key', default) # seguro |
| try/except KeyError en cada acceso | Un solo get() sin bloques de excepción |
setdefault() y update()
setdefault(clave, defecto) retorna el valor si la clave existe; si no, la inserta con el valor por defecto y lo retorna. update() fusiona otro dict o iterable de pares en el existente.
# setdefault: insertar solo si la clave no existe
inventario: dict[str, list] = {}
# Sin setdefault — más verboso
if "frutas" not in inventario:
inventario["frutas"] = []
inventario["frutas"].append("manzana")
# Con setdefault — más conciso
inventario.setdefault("verduras", []).append("zanahoria")
inventario.setdefault("verduras", []).append("lechuga")
# La segunda llamada no sobreescribe — ya existe "verduras"
print(inventario)
# {'frutas': ['manzana'], 'verduras': ['zanahoria', 'lechuga']}
# update: fusionar dicts
config = {"host": "localhost", "port": 5432}
overrides = {"port": 3000, "debug": True}
config.update(overrides) # modifica config en el lugar
print(config)
# {'host': 'localhost', 'port': 3000, 'debug': True}
# update también acepta keyword arguments
config.update(timeout=30, pool_size=5)
print(config){'frutas': ['manzana'], 'verduras': ['zanahoria', 'lechuga']}
{'host': 'localhost', 'port': 3000, 'debug': True}
{'host': 'localhost', 'port': 3000, 'debug': True, 'timeout': 30, 'pool_size': 5}pop(), popitem() y dict.fromkeys()
pop() elimina y retorna un valor. popitem() elimina y retorna el último par insertado (LIFO). dict.fromkeys() crea un dict con un conjunto de claves y un valor uniforme.
datos = {"a": 1, "b": 2, "c": 3, "d": 4}
# pop(clave): elimina y retorna el valor
valor = datos.pop("b")
print(valor) # 2
print(datos) # {'a': 1, 'c': 3, 'd': 4}
# pop con valor por defecto — evita KeyError
faltante = datos.pop("z", None)
print(faltante) # None
# popitem(): elimina y retorna el último par (útil para procesar LIFO)
ultimo = datos.popitem()
print(ultimo) # ('d', 4)
print(datos) # {'a': 1, 'c': 3}
# dict.fromkeys(): crear un dict con claves predefinidas y valor uniforme
claves = ["nombre", "email", "telefono"]
perfil_vacio = dict.fromkeys(claves, "")
print(perfil_vacio)
# {'nombre': '', 'email': '', 'telefono': ''}
# Útil también para inicializar contadores
palabras = ["python", "es", "genial"]
contadores = dict.fromkeys(palabras, 0)
print(contadores) # {'python': 0, 'es': 0, 'genial': 0}2
{'a': 1, 'c': 3, 'd': 4}
None
('d', 4)
{'a': 1, 'c': 3}
{'nombre': '', 'email': '', 'telefono': ''}
{'python': 0, 'es': 0, 'genial': 0}dict.fromkeys(claves, []) hace que todas las claves apunten a la misma lista. Mutar esa lista afecta a todas las entradas. Para valores mutables independientes, usa una dict comprehension: {k: [] for k in claves}.