python agregar - Eliminar un elemento de un diccionario




7 Answers

La declaración del elimina un elemento:

del d[key]

Sin embargo, esto muta el diccionario existente, por lo que el contenido del diccionario cambia para cualquier otra persona que tenga una referencia a la misma instancia. Para devolver un nuevo diccionario, haga una copia del diccionario:

def removekey(d, key):
    r = dict(d)
    del r[key]
    return r

El constructor dict() hace una copia superficial . Para hacer una copia en profundidad, consulte el módulo de copy .

Tenga en cuenta que hacer una copia para cada dict del / asignación / etc. significa que vas de un tiempo constante a un tiempo lineal, y también estás usando un espacio lineal. Para pequeños dados, esto no es un problema. Pero si planea hacer muchas copias de grandes dictados, probablemente desee una estructura de datos diferente, como un HAMT (como se describe en esta respuesta ).

elementos lista

¿Hay alguna forma de eliminar un elemento de un diccionario en Python?

Además, ¿cómo puedo eliminar un elemento de un diccionario para devolver una copia (es decir, sin modificar el original)?




Creo que tu solución es la mejor manera de hacerlo. Pero si desea otra solución, puede crear un nuevo diccionario utilizando las claves de un diccionario antiguo sin incluir su clave especificada, como esto:

>>> a
{0: 'zero', 1: 'one', 2: 'two', 3: 'three'}
>>> {i:a[i] for i in a if i!=0}
{1: 'one', 2: 'two', 3: 'three'}



Hay muchas respuestas agradables, pero quiero enfatizar una cosa.

Puede usar tanto el método dict.pop() como una declaración más genérica para eliminar elementos de un diccionario. Ambos mutan el diccionario original, por lo que necesita hacer una copia (vea los detalles a continuación).

Y ambos generarán un 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 encargarte 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)

mediante la realización de un control:

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 con pop() también hay una forma mucho más concisa: proporcionar 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 use pop() para obtener el valor de una clave que se está eliminando, puede proporcionar cualquier cosa, no necesariamente None . Aunque podría ser que el uso de del with in check sea un poco más rápido debido a que pop() es una función con sus propias complicaciones que causan sobrecarga. Normalmente no es el caso, por lo que pop() con 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), utilizando copy.copy() o dict.copy() , podría ser suficiente . El diccionario mantiene una referencia al objeto como un valor para una clave. Por lo tanto, cuando elimina una clave de un diccionario, esta referencia se elimina, 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 la copia superficial, por lo que disminuye el rendimiento del código al hacer la copia, desperdiciar memoria y proporcionar 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 poco profunda:

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}



Simplemente llame a del d ['clave'].

Sin embargo, en producción, siempre es una buena práctica verificar si existe una 'clave' en d.

if 'key' in d:
    del d['key']



No, no hay otra manera que

def dictMinus(dct, val):
   copy = dct.copy()
   del copy[val]
   return copy

Sin embargo, a menudo crear copias de diccionarios ligeramente alterados probablemente no sea una buena idea porque dará lugar a demandas de memoria comparativamente grandes. Por lo general, es mejor registrar el diccionario antiguo (si es necesario) y luego modificarlo.




Aquí un enfoque de diseño de nivel superior:

def eraseElement(d,k):
    if isinstance(d, dict):
        if k in d:
            d.pop(k)
            print(d)
        else:
            print("Cannot find matching key")
    else:
        print("Not able to delete")


exp = {'A':34, 'B':55, 'C':87}
eraseElement(exp, 'C')

Paso el diccionario y la clave que quiero a mi función, valida si es un diccionario y si la clave está bien, y si existen ambas, elimina el valor del diccionario e imprime las sobras.

Salida: {'B': 55, 'A': 34}

¡Espero que ayude!




A continuación, el fragmento de código te ayudará definitivamente. He agregado comentarios en cada línea que te ayudarán a entender el código.

def execute():
   dic = {'a':1,'b':2}
   dic2 = remove_key_from_dict(dic, 'b')  
   print(dict2)           # {'a': 1}
   print(dict)            # {'a':1,'b':2}

def remove_key_from_dict(dictionary_to_use, key_to_delete):
   copy_of_dict = dict(dictionary_to_use)     # creating clone/copy of the dictionary
   if key_to_delete in copy_of_dict :         # checking given key is present in the dictionary
       del copy_of_dict [key_to_delete]       # deleting the key from the dictionary 
   return copy_of_dict                        # returning the final dictionary

o también puedes usar dict.pop ()

d = {"a": 1, "b": 2}

res = d.pop("c")  # No `KeyError` here
print (res)       # this line will not execute

o el mejor enfoque es

res = d.pop("c", "key not found")
print (res)   # key not found
print (d)     # {"a": 1, "b": 2}

res = d.pop("b", "key not found")
print (res)   # 2
print (d)     # {"a": 1}



Related