Hay muchas respuestas agradables, pero quiero enfatizar una cosa.
Puede usar tanto el dict.pop()
método como una del
declaración más genérica para eliminar elementos de un diccionario. Ambos mutan el diccionario original, por lo que debe hacer una copia (consulte los detalles a continuación).
Y ambos aparecerán KeyError
si la clave que les está proporcionando no está presente en el diccionario:
key_to_remove = "c"
d = {"a": 1, "b": 2}
del d[key_to_remove] # Raises `KeyError: 'c'`
y
key_to_remove = "c"
d = {"a": 1, "b": 2}
d.pop(key_to_remove) # Raises `KeyError: 'c'`
Tienes que ocuparte de esto:
capturando la excepción:
key_to_remove = "c"
d = {"a": 1, "b": 2}
try:
del d[key_to_remove]
except KeyError as ex:
print("No such key: '%s'" % ex.message)
y
key_to_remove = "c"
d = {"a": 1, "b": 2}
try:
d.pop(key_to_remove)
except KeyError as ex:
print("No such key: '%s'" % ex.message)
realizando una verificación:
key_to_remove = "c"
d = {"a": 1, "b": 2}
if key_to_remove in d:
del d[key_to_remove]
y
key_to_remove = "c"
d = {"a": 1, "b": 2}
if key_to_remove in d:
d.pop(key_to_remove)
pero pop()
también hay una forma mucho más concisa: proporcione el valor de retorno predeterminado:
key_to_remove = "c"
d = {"a": 1, "b": 2}
d.pop(key_to_remove, None) # No `KeyError` here
A menos que utilice pop()
para obtener el valor de una clave que se eliminará, puede proporcionar cualquier cosa, no necesaria None
. Aunque podría ser que usarlo del
con in
check es un poco más rápido debido a que pop()
es una función con sus propias complicaciones que causan sobrecarga. Por lo general, no es el caso, por lo que pop()
con el valor predeterminado es lo suficientemente bueno.
En cuanto a la pregunta principal, tendrá que hacer una copia de su diccionario, guardar el diccionario original y tener uno nuevo sin quitar la clave.
Algunas otras personas aquí sugieren hacer una copia completa (profunda) con copy.deepcopy()
, que podría ser una exageración, una copia "normal" (superficial), usando copy.copy()
o dict.copy()
, podría ser suficiente. El diccionario mantiene una referencia al objeto como valor para una clave. Entonces, cuando elimina una clave de un diccionario, se elimina esta referencia, no el objeto al que se hace referencia. El objeto en sí puede ser eliminado más tarde automáticamente por el recolector de basura, si no hay otras referencias para él en la memoria. Hacer una copia profunda requiere más cálculos en comparación con una copia superficial, por lo que disminuye el rendimiento del código al hacer la copia, desperdiciando memoria y proporcionando más trabajo al GC, a veces una copia superficial es suficiente.
Sin embargo, si tiene objetos mutables como valores de diccionario y planea modificarlos más adelante en el diccionario devuelto sin la clave, debe hacer una copia profunda.
Con copia superficial:
def get_dict_wo_key(dictionary, key):
"""Returns a **shallow** copy of the dictionary without a key."""
_dict = dictionary.copy()
_dict.pop(key, None)
return _dict
d = {"a": [1, 2, 3], "b": 2, "c": 3}
key_to_remove = "c"
new_d = get_dict_wo_key(d, key_to_remove)
print(d) # {"a": [1, 2, 3], "b": 2, "c": 3}
print(new_d) # {"a": [1, 2, 3], "b": 2}
new_d["a"].append(100)
print(d) # {"a": [1, 2, 3, 100], "b": 2, "c": 3}
print(new_d) # {"a": [1, 2, 3, 100], "b": 2}
new_d["b"] = 2222
print(d) # {"a": [1, 2, 3, 100], "b": 2, "c": 3}
print(new_d) # {"a": [1, 2, 3, 100], "b": 2222}
Con copia profunda:
from copy import deepcopy
def get_dict_wo_key(dictionary, key):
"""Returns a **deep** copy of the dictionary without a key."""
_dict = deepcopy(dictionary)
_dict.pop(key, None)
return _dict
d = {"a": [1, 2, 3], "b": 2, "c": 3}
key_to_remove = "c"
new_d = get_dict_wo_key(d, key_to_remove)
print(d) # {"a": [1, 2, 3], "b": 2, "c": 3}
print(new_d) # {"a": [1, 2, 3], "b": 2}
new_d["a"].append(100)
print(d) # {"a": [1, 2, 3], "b": 2, "c": 3}
print(new_d) # {"a": [1, 2, 3, 100], "b": 2}
new_d["b"] = 2222
print(d) # {"a": [1, 2, 3], "b": 2, "c": 3}
print(new_d) # {"a": [1, 2, 3, 100], "b": 2222}