lista elementos ejemplo diccionarios diccionario dentro declarar convertir agregar python dictionary pop del

elementos - diccionarios python



Eliminar un elemento de un diccionario (14)

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

Un dict es la estructura de datos incorrecta que se utiliza para esto.

Claro, copiar el dictado y hacer estallar desde las obras de copia, y también lo hace la construcción de un nuevo dictado con una comprensión, pero toda esa copia lleva tiempo: ha reemplazado una operación de tiempo constante con una de tiempo lineal. Y todas esas copias vivas toman espacio al mismo tiempo: espacio lineal por copia.

Otras estructuras de datos, como los intentos mapeados de la matriz de hash , están diseñados para este tipo de casos de uso: la adición o eliminación de un elemento devuelve una copia en tiempo logarítmico, compartiendo la mayor parte de su almacenamiento con el original . 1

Por supuesto hay algunas desventajas. El rendimiento es logarítmico en lugar de constante (aunque con una base grande, generalmente 32-128). Y, aunque puede hacer que la API no mutante sea idéntica a la dict , la API "mutante" es obviamente diferente. Y, sobre todo, no hay baterías HAMT incluidas con Python. 2

La biblioteca pyrsistent es una implementación bastante sólida de reemplazos de dict basados ​​en HAMT (y varios otros tipos) para Python. Incluso tiene una API de nifty evolver para portar el código mutante existente a un código persistente de la mejor manera posible. Pero si desea ser explícito acerca de devolver copias en lugar de mutar, simplemente lo utiliza así:

>>> from pyrsistent import m >>> d1 = m(a=1, b=2) >>> d2 = d1.set(''c'', 3) >>> d3 = d1.remove(''a'') >>> d1 pmap({''a'': 1, ''b'': 2}) >>> d2 pmap({''c'': 3, ''a'': 1, ''b'': 2}) >>> d3 pmap({''b'': 2})

Que d3 = d1.remove(''a'') es exactamente lo que está preguntando la pregunta.

Si tiene estructuras de datos mutables como dict y list incrustadas en el pmap , seguirá teniendo problemas con el alias; solo puede solucionarlo si se mantiene inmutable hasta el fondo, incorporando pmap sy pvector s.

1. Los HAMT también se han hecho populares en lenguajes como Scala, Clojure, Haskell porque juegan muy bien con la programación sin bloqueo y la memoria transaccional del software, pero ninguno de ellos es muy relevante en Python.

2. De hecho, hay un HAMT en el stdlib, utilizado en la implementación de contextvars . El PEP retirado anteriormente explica por qué. Pero este es un detalle de implementación oculto de la biblioteca, no un tipo de colección pública.

¿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)?


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}


Aquí hay otra variación usando lista de comprensión:

original_d = {''a'': None, ''b'': ''Some''} d = dict((k,v) for k, v in original_d.iteritems() if v) # result should be {''b'': ''Some''}

El enfoque se basa en una respuesta de este post: una manera eficiente de eliminar claves de cadenas de un dict.


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!


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}


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 ).


La declaración del es lo que estás buscando. Si tienes un diccionario llamado foo con una clave llamada ''barra'', puedes eliminar la ''barra'' de foo así:

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

La llamada de dict hace una copia superficial. Si desea una copia profunda, utilice 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


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.


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


agradable de una sola línea para verificar si la clave está presente, eliminarla, devolver el valor o el valor predeterminado:

ret_val = (''key'' in body and body.pop(''key'')) or 5


pop muta el diccionario.

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

Si desea conservar el original, simplemente puede copiarlo.


>>> def delete_key(dict, key): ... del dict[key] ... return dict ... >>> test_dict = {''one'': 1, ''two'' : 2} >>> print delete_key(test_dict, ''two'') {''one'': 1} >>>

esto no hace ningún manejo de errores, asume que la clave está en el dictado, es posible que desee comprobar eso primero y raise si no está


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

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