Pregunta Eliminar un elemento de un diccionario


¿Hay alguna manera 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, no modificar el original)?


842
2018-04-30 21:20


origen


Respuestas:


los del declaración elimina un elemento:

del d[key]

Sin embargo, esto muta el diccionario existente para que el contenido del diccionario cambie 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

los dict() constructor hace una copia superficial. Para hacer una copia profunda, vea el copy módulo.


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


1184
2018-04-30 21:25



pop muta el diccionario.

 >>>lol = {"hello":"gdbye"}
 >>>lol.pop("hello")
    'gdbye'
 >>> lol
     {}

Si quiere conservar el original, simplemente puede copiarlo.


130
2018-03-21 16:22



Creo que tu solución es la mejor manera de hacerlo. Pero si quiere otra solución, puede crear un nuevo diccionario utilizando las claves del diccionario antiguo sin incluir su clave específica, como esta:

>>> 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'}

55
2018-04-30 21:26



los declaración es lo que estás buscando. Si tiene un diccionario llamado foo con una clave llamada 'barra', puede eliminar 'barra' de foo de esta manera:

del foo['bar']

Tenga en cuenta que esto modifica permanentemente el diccionario que se está operando. Si desea conservar el diccionario original, deberá crear una copia de antemano:

>>> foo = {'bar': 'baz'}
>>> fu = dict(foo)
>>> del foo['bar']
>>> print foo
{}
>>> print fu
{'bar': 'baz'}

los dict llamada hace una copia superficial. Si quieres una copia profunda, usa copy.deepcopy.

Aquí hay un método que puede copiar y pegar, para su conveniencia:

def minus_key(key, dictionary):
    shallow_copy = dict(dictionary)
    del shallow_copy[key]
    return shallow_copy

47
2018-04-30 21:23



d = {1: 2, '2': 3, 5: 7}
del d[5]
print 'd = ', d

Resultado: d = {1: 2, '2': 3}


16
2018-04-30 21:24



Hay muchas buenas respuestas, pero quiero enfatizar una cosa.

Puedes usar ambos dict.pop() método y un más genérico del declaración para eliminar elementos de un diccionario. Ambos cambian el diccionario original, por lo que debes hacer una copia (ver detalles a continuación).

Y ambos levantarán un KeyError si la clave que les proporciona 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 encargarme de esto:

al capturar 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 un cheque:

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: 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 uses pop() para obtener el valor de una clave que se elimina puede proporcionar cualquier cosa, no es necesario None. Aunque podría ser que usar del con in el cheque es ligeramente más rápido debido a pop() siendo una función con sus propias complicaciones que causan gastos generales. Usualmente no es el caso, entonces 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 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 recolector de elementos no utilizados puede eliminar el objeto automáticamente más adelante, 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 poco profunda, por lo que disminuye el rendimiento del código al hacer la copia, desperdiciando la memoria y proporcionando más trabajo al GC; a veces, la copia poco profunda 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 una 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}

16
2017-09-21 19:52



Simplemente llame a del d ['key'].

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

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

12
2018-03-02 13:39



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, ya que resultará en demandas de memoria comparativamente grandes. Por lo general, es mejor registrar el diccionario antiguo (si es necesario) y luego modificarlo.


6
2018-04-30 21:27