¿Cómo puedo eliminar una clave de un diccionario de Python?

Al eliminar una clave de un diccionario, uso:

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

¿Hay una forma de una línea de hacer esto?

preguntado el 30 de junio de 12 a las 21:06

Script de referencia para los diversos métodos propuestos en las respuestas a esta pregunta: gist.github.com/zigg/6280653 -

¿Responde esto a tu pregunta? Eliminar un elemento de un diccionario -

14 Respuestas

Para eliminar una clave sin importar si está en el diccionario, use la forma de dos argumentos de dict.pop():

my_dict.pop('key', None)

Esto volverá my_dict[key] if key existe en el diccionario, y None de lo contrario. Si no se especifica el segundo parámetro (es decir, my_dict.pop('key')) y key no existe, un KeyError es elevado.

Para eliminar una clave cuya existencia está garantizada, también puede usar:

del my_dict['key']

Esto levantará un KeyError si la clave no está en el diccionario.

Respondido 25 ago 21, 13:08

A veces una ventaja de usar pop() encima del: devuelve el valor de esa clave. De esta manera, puede obtener y eliminar una entrada de un dictado en una línea de código. - Kratenko

En la pregunta no se requiere mantener el valor. Esto solo agregaría una complejidad innecesaria. La respuesta de @zigg (abajo) es mucho mejor. - salvatore cosentino

@SalvatoreCosentino No puedo seguir tu argumento. ¿Por qué el código de esta respuesta es más complejo que el código de la otra respuesta? - Sven Marnach

@SalvatoreCosentino No, ignorar el valor de retorno de una función no es nada ineficiente. Todo lo contrario: esta solución es mucho más rápida que la try/except solución si la clave no existe. Puede encontrar uno u otro más fácil de leer, lo cual está bien. Ambos son Python idiomáticos, así que elige lo que prefieras. Pero afirmar que esta respuesta es más compleja o ineficiente simplemente no tiene sentido. - Sven Marnach

@ user5359531 No entiendo. ¿Cómo es esto un problema? Ninguno de los métodos en los tipos integrados de Python devuelve self, por lo que sería bastante sorprendente si este lo hiciera. - Sven Marnach

Específicamente para responder "¿hay una forma de una línea de hacer esto?"

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

... bueno, tú preguntaron ;-)

Sin embargo, debe considerar que esta forma de eliminar un objeto de un dict is no atómico-es posible que 'key' tal vez en my_dict durante el if declaración, pero se puede eliminar antes del se ejecuta, en cuyo caso del fallará con un KeyError. Dado esto, sería más seguro utilizan el dict.pop o algo parecido a

try:
    del my_dict['key']
except KeyError:
    pass

que, por supuesto, es definitivamente no una sola línea.

Respondido 03 Abr '20, 09:04

Si, pop es definitivamente más conciso, aunque hay una ventaja clave de hacerlo de esta manera: queda inmediatamente claro lo que está haciendo. - zigg

EL try/except declaración es más cara. Generar una excepción es lento. - Chris Barker

@ChrisBarker He encontrado si existe la clave, try es marginalmente más rápido, aunque si no lo hace, try es de hecho mucho más lento. pop es bastante consistente pero más lento que todos menos try con una clave no presente. Ver gist.github.com/zigg/6280653. En última instancia, depende de la frecuencia con la que espera que la clave esté realmente en el diccionario, y de si necesita atomicidad o no y, por supuesto, si está realizando una optimización prematura o no;) - zigg

Creo que el valor de la claridad no debe pasarse por alto. +1 por esto. - Juan Carlos Coto

con respecto al costo de probar/excepto, también puede ir if 'key' in mydict: #then del.... Necesitaba sacar una clave/valor de un dictado para analizar correctamente, pop no era una solución perfecta. - Marc

Me tomó algún tiempo averiguar qué es exactamente my_dict.pop("key", None) está haciendo. Así que agregaré esto como respuesta para ahorrar tiempo de búsqueda en Google:

pop(key[, default])

If clave está en el diccionario, elimínelo y devuelva su valor, de lo contrario, devuelva tu préstamo estudiantil. Si tu préstamo estudiantil no se da y clave no está en el diccionario, un KeyError es elevado.

Documentación

Respondido el 02 de enero de 21 a las 01:01

Simplemente escriba ayuda (dict.pop) en el intérprete de python. - david mulder

help() y dir() pueden ser tus amigos cuando necesites saber qué hace algo. - david mulder

or dict.pop? en IPython. - erik kaplun

del my_dict[key] es un poco más rápido que my_dict.pop(key) para eliminar una clave de un diccionario cuando la clave existe

>>> import timeit
>>> setup = "d = {i: i for i in range(100000)}"

>>> timeit.timeit("del d[3]", setup=setup, number=1)
1.79e-06
>>> timeit.timeit("d.pop(3)", setup=setup, number=1)
2.09e-06
>>> timeit.timeit("d2 = {key: val for key, val in d.items() if key != 3}", setup=setup, number=1)
0.00786

Pero cuando la clave no existe if key in my_dict: del my_dict[key] es un poco más rápido que my_dict.pop(key, None). Ambos son al menos tres veces más rápidos que del en un parche de try/except declaración:

>>> timeit.timeit("if 'missing key' in d: del d['missing key']", setup=setup)
0.0229
>>> timeit.timeit("d.pop('missing key', None)", setup=setup)
0.0426
>>> try_except = """
... try:
...     del d['missing key']
... except KeyError:
...     pass
... """
>>> timeit.timeit(try_except, setup=setup)
0.133

Respondido 03 Abr '20, 10:04

@Boris: esto es útil como ejercicio general. - k--

@daisy lo que digo es que debe elegir la sintaxis más legible, no la operación que es 300 nanosegundos más rápida (esa es literalmente la diferencia entre del y pop del primer conjunto de tiempos arriba) - Boris

Además, estas operaciones son tan rápidas que estos tiempos no son confiables. - Boris

Si necesita eliminar muchas claves de un diccionario en una línea de código, creo que usar map() es bastante sucinto y legible en Pythonic:

myDict = {'a':1,'b':2,'c':3,'d':4}
map(myDict.pop, ['a','c']) # The list of keys to remove
>>> myDict
{'b': 2, 'd': 4}

Y si necesita detectar errores en los que aparece un valor que no está en el diccionario, use lambda dentro del mapa () de esta manera:

map(lambda x: myDict.pop(x,None), ['a', 'c', 'e'])
[1, 3, None] # pop returns
>>> myDict
{'b': 2, 'd': 4}

ó en python3, debe usar una lista de comprensión en su lugar:

[myDict.pop(x, None) for x in ['a', 'c', 'e']]

Funciona. Y 'e' no causó un error, aunque myDict no tenía una tecla 'e'.

contestado el 07 de mayo de 19 a las 21:05

Esto no funcionará en Python 3 porque map y los amigos ahora son perezosos y devuelven iteradores. Utilizando map para los efectos secundarios generalmente se considera una mala práctica; un estandar for ... in bucle sería mejor. Ver Vistas e iteradores en lugar de listas para más información. - Greg Krimer

Independientemente del gusto y el estilo de práctica, las listas de comprensión aún deberían funcionar en Py3 [myDict.pop(i, None) for i in ['a', 'c']], ya que ofrecen una alternativa general a map (y filter). - miguel ekoka

@MichaelEkoka, no debe usar listas de comprensión por sus efectos secundarios, use una lista regular for ... in círculo. - Boris

@Boris Probablemente tengas razón. Mi respuesta es específicamente relacionada con el uso map(), que a menudo se utiliza por sus efectos secundarios. La alternativa recomendada en Python is la comprensión de la lista, que en mi opinión sigue siendo bastante legible y cognitivamente ligera como una sola línea (ver pregunta). Usados ​​solo por sus efectos secundarios, ambos constructos dan como resultado una lista inútil, que puede ser ineficiente. A partir de Python3, no conozco una función integrada que pueda iterar de forma segura y elegante a través de una expresión generadora, sin un subproducto costoso, por ejemplo loop(d.pop(k) for k in ['a', 'b']). - miguel ekoka

@MichaelEkoka la "función incorporada" es un bucle for: for k in ['a', 'b']: d.pop(k). ¿Por qué necesitas una forma diferente de hacerlo? Si necesita que ocupe solo una línea tan mal, puede colocar la segunda parte del bucle for en la misma línea. - Boris

Puedes utilizar una comprensión del diccionario para crear un nuevo diccionario con esa clave eliminada:

>>> my_dict = {k: v for k, v in my_dict.items() if k != 'key'}

Puede eliminar por condiciones. No hay error si key no existe

Respondido 03 Abr '20, 09:04

Esta respuesta es diferente a las demás porque no tiene efectos secundarios (no muta el diccionario original). - jeff d blanco

Si bien esta es probablemente la forma en que yo también lo haría, esto crea un diccionario completamente nuevo en la memoria, copiando (referencias a) objetos al nuevo diccionario. Luego lo guarda en el nombre anterior. Para diccionarios grandes, esto puede llevar algún tiempo. del dict[key] or dict.pop(key) será más rápido en todos los casos. - mazunki

Usando la palabra clave "del":

del dict[key]

contestado el 29 de mayo de 18 a las 14:05

Podemos eliminar una clave de un diccionario de Python mediante algunos de los siguientes enfoques.

Usando el del palabra clave; Sin embargo, es casi el mismo enfoque que tú:

 myDict = {'one': 100, 'two': 200, 'three': 300 }
 print(myDict)  # {'one': 100, 'two': 200, 'three': 300}
 if myDict.get('one') : del myDict['one']
 print(myDict)  # {'two': 200, 'three': 300}

Or

Podemos hacer lo siguiente:

Pero uno debe tener en cuenta que, en este proceso, en realidad no borrar cualquier clave del diccionario en lugar de hacer una clave específica excluidos de ese diccionario. Además, observé que devolvía un diccionario que no estaba ordenado igual que myDict.

myDict = {'one': 100, 'two': 200, 'three': 300, 'four': 400, 'five': 500}
{key:value for key, value in myDict.items() if key != 'one'}

Si lo ejecutamos en el shell, ejecutará algo como {'five': 500, 'four': 400, 'three': 300, 'two': 200} - fíjate que no es lo mismo ordenado que myDict. Nuevamente si tratamos de imprimir myDict, entonces podemos ver todas las claves, incluidas las que excluimos del diccionario con este enfoque. Sin embargo, podemos hacer un nuevo diccionario asignando la siguiente declaración a una variable:

var = {key:value for key, value in myDict.items() if key != 'one'}

Ahora, si tratamos de imprimirlo, seguirá el orden principal:

print(var) # {'two': 200, 'three': 300, 'four': 400, 'five': 500}

Or

Usando el pop() método.

myDict = {'one': 100, 'two': 200, 'three': 300}
print(myDict)

if myDict.get('one') : myDict.pop('one')
print(myDict)  # {'two': 200, 'three': 300}

La diferencia entre los del y pop es que, usando pop() método, en realidad podemos almacenar el valor de la clave si es necesario, como el siguiente:

myDict = {'one': 100, 'two': 200, 'three': 300}
if myDict.get('one') : var = myDict.pop('one')
print(myDict) # {'two': 200, 'three': 300}
print(var)    # 100

Horquilla esta esencia para referencia futura, si lo encuentra útil.

contestado el 05 de mayo de 21 a las 03:05

No use if myDict.get('one') para comprobar si una clave está presente! Falla si myDict['one'] tiene un valor falso. Además, los dictados no tienen un orden inherente, por lo que no tiene sentido mencionarlo. - Robar

Los dictados de @Rob se ordenan por orden de inserción a partir de CPython 3.6 y todas las demás implementaciones de Python a partir de 3.7. - Boris

Puede usar el manejo de excepciones si quiere ser muy detallado:

try: 
    del dict[key]

except KeyError: pass

Esto es más lento, sin embargo, que el pop() método, si la clave no existe.

my_dict.pop('key', None)

No importará para algunas teclas, pero si lo haces repetidamente, entonces el último método es una mejor opción.

El enfoque más rápido es este:

if 'key' in dict: 
    del myDict['key']

Pero este método es peligroso porque si 'key' se elimina entre las dos líneas, un KeyError será criado

contestado el 25 de mayo de 19 a las 05:05

Diccionario tipo de datos tiene un método llamado dict_name.pop(item) y esto se puede utilizar para eliminar un valor clave par de un diccionario.

a={9:4,2:3,4:2,1:3}
a.pop(9)
print(a)

Esto dará la salida como:

{2: 3, 4: 2, 1: 3}

De esta manera, puede eliminar un elemento de un diccionario en una línea.

Respondido el 21 de junio de 20 a las 10:06

Otra forma es usando items() + dict comprension.

items() junto con la comprensión de dictados también pueden ayudarnos a lograr la tarea de eliminar el par clave-valor, pero tiene el inconveniente de no ser una técnica de dictado en su lugar. En realidad, se crea un nuevo dictado excepto por la clave que no deseamos incluir.

test_dict = {"sai" : 22, "kiran" : 21, "vinod" : 21, "sangam" : 21}

# Printing dictionary before removal
print ("dictionary before performing remove is : " + str(test_dict))

# Using items() + dict comprehension to remove a dict. pair
# removes  vinod
new_dict = {key:val for key, val in test_dict.items() if key != 'vinod'}

# Printing dictionary after removal
print ("dictionary after remove is : " + str(new_dict))

Salida:

dictionary before performing remove is : {'sai': 22, 'kiran': 21, 'vinod': 21, 'sangam': 21}
dictionary after remove is : {'sai': 22, 'kiran': 21, 'sangam': 21}

Respondido el 02 de enero de 21 a las 01:01

esto en realidad no hace lo que se le pide: crea un nuevo dict con las claves no deseadas eliminadas. Además, iterar sobre todas las claves para eliminar una es realizar una operación O(1) en tiempo O(N). - anon01

Prefiero la versión inmutable.

foo = {
    1:1,
    2:2,
    3:3
}
removeKeys = [1,2]
def woKeys(dct, keyIter):
    return {
        k:v
        for k,v in dct.items() if k not in keyIter
    }

>>> print(woKeys(foo, removeKeys))
{3: 3}
>>> print(foo)
{1: 1, 2: 2, 3: 3}

Respondido el 14 de junio de 19 a las 09:06

Filtro único en clave

  • devolver "clave" y eliminarlo de my_dict si existe "clave" en my_dict
  • devolver Ninguno si "clave" no existe en my_dict

esto va a cambiar my_dict en su lugar (mutable)

my_dict.pop('key', None)

Múltiples filtros en las claves

generar un nuevo dict (inmutable)

dic1 = {
    "x":1,
    "y": 2,
    "z": 3
}

def func1(item):
    return  item[0]!= "x" and item[0] != "y"

print(
    dict(
        filter(
            lambda item: item[0] != "x" and item[0] != "y", 
            dic1.items()
            )
    )
)

Respondido 25 Abr '20, 17:04

También podrías usar filter con lambda:

>>> d = {'a': 1, 'b': 2, 'c': 3}
>>> dict(filter(lambda x: x[0] != 'a', d.items()))
{'b': 2, 'c': 3}
>>>

Respondido el 12 de Septiembre de 21 a las 03:09

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.