¿Cuál es la mejor manera de eliminar un elemento del diccionario por valor en python?

Me pregunto si hay una forma sencilla de eliminar uno o más elementos del diccionario de un diccionario de Python por valor .

Tenemos un diccionario llamado myDict :

 myDict = {1:"egg", "Answer":42, 8:14, "foo":42} 

y desea eliminar todos los elementos cuyos valores son iguales a 42 .

Sugerencia de implementación:

  1. Obtenga una lista de todas las claves de un determinado valor en myDict
    (Ver por ejemplo obtener clave por valor en el diccionario .)

  2. Eliminar este elemento o elementos dict (basados ​​en las claves encontradas) de myDict
    (Para obtener más información, consulte Eliminar un elemento de un diccionario ).

Entonces, ¿cuál crees que es la forma más elegante y más “pythonica” de implementar este problema en Python?

Puedes usar un simple dict :

 myDict = {key:val for key, val in myDict.items() if val != 42} 

Como tal:

 >>> {key:val for key, val in myDict.items() if val != 42} {8: 14, 1: 'egg'} 

Debe crear una copia para iterar una vez que cambiar el tamaño del diccionario dentro de un bucle provoca un RunTimeError. Iterar sobre la clave, los pares de valores en su diccionario se copian usando elementos () y compare cada valor con el valor que está buscando. Si coinciden, elimine la clave del diccionario.

  for key, value in dict(myDict).items(): if value == 42: del mydict[key] 

Agregando respuesta por pregunta en los comentarios a continuación, ya que era demasiado grande para un comentario. Aquí hay una sesión de consola rápida que muestra que mydict.copy() y dict(myDict) logran lo mismo.

 >>>import copy >>>dict1 = {1:"egg", "Answer":42, 8:14, "foo":42} >>>dict2 = dict(dict1) >>>dict3 = dict1.copy() >>>dict4 = dict1 >>>dict1[1] = "egg sandwich" >>>dict1 {'Answer': 42, 1: 'egg sandwich', 'foo': 42, 8: 14} >>>dict2 {'Answer': 42, 1: 'egg', 'foo': 42, 8: 14} >>>dict3 {'Answer': 42, 1: 'egg', 'foo': 42, 8: 14} >>>dict4 {'Answer': 42, 1: 'egg sandwich', 'foo': 42, 8: 14} >>>dict2['foo'] = "I pity the" dict1 >>>{'Answer': 42, 1: 'egg sandwich', 'foo': 42, 8: 14} >>>dict2 {'Answer': 42, 1: 'egg', 'foo': 'I pity the', 8: 14} >>>dict3 {'Answer': 42, 1: 'egg', 'foo': 42, 8: 14} >>>dict4 {'Answer': 42, 1: 'egg sandwich', 'foo': 42, 8: 14} >>>dict4[8] = "new" >>>dict1 {'Answer': 42, 1: 'egg sandwich', 'foo': 42, 8: 'new'} >>>dict2 {'Answer': 42, 1: 'egg', 'foo': 'I pity the', 8: 14} >>>dict3 {'Answer': 42, 1: 'egg', 'foo': 42, 8: 14} >>>dict4 {'Answer': 42, 1: 'egg sandwich', 'foo': 42, 8: 'new'} ` 

Me gusta seguir un enfoque de “lista de resultados” en el que recorre el diccionario, luego agregue los que desea eliminar a una lista, luego, después de iterar, elimine las entradas de esa lista de la siguiente manera:

hitList = [] para dictEntry: si la condición de prueba, hitList.append

para la entrada en hitList: delete dict [entry]

esto es solo un pseudocódigo pero he tenido éxito con esto en el pasado

Puedes iterar sobre una copia y hacer una búsqueda:

 for k in myDict.copy(): if myDict[k] == 42: del myDict[k] 

O solo copia las claves:

 myDict = {1:"egg", "Answer":42, 8:14, "foo":42} for k in list(myDict): if myDict[k] == 42: del myDict[k] print(myDict) {8: 14, 1: 'egg'} 

Que si quieres mutar el dictado original debería ser el más eficiente.

Usa un diccionario de comprensión.

Si necesitas una copia usa iteritems()

 >>> {k:v for k, v in myDict.iteritems() if v!=42} {8: 14, 1: 'egg'} 

Si no necesita una copia de su diccionario, puede usar viewitems()

 >>> {k:v for k, v in myDict.viewitems() if v!=42} {8: 14, 1: 'egg'}