Eliminar un elemento de un diccionario cuando su clave es desconocida

¿Cuál es la mejor manera de eliminar un elemento de un diccionario por valor, es decir, cuando la clave del elemento es desconocida? He aquí un método sencillo:

for key, item in some_dict.items():
    if item is item_to_remove:
        del some_dict[key]

¿Hay formas mejores? ¿Hay algo malo en mutar (borrar elementos) del diccionario mientras se itera?

Solución

Tenga en cuenta que actualmente está probando la identidad de los objetos (es sólo devuelve Verdadero si ambos operandos están representados por el mismo objeto en la memoria - esto no es siempre el caso con dos objetos que se comparan igual con ==). Si estás haciendo esto a propósito, entonces podrías reescribir tu código como

some_dict = {key: value for key, value in some_dict.items() 
             if value is not value_to_remove}

Pero esto puede no hacer lo que quieres:

>>> some_dict = {1: "Hello", 2: "Goodbye", 3: "You say yes", 4: "I say no"}
>>> value_to_remove = "You say yes"
>>> some_dict = {key: value for key, value in some_dict.items() if value is not value_to_remove}
>>> some_dict
{1: 'Hello', 2: 'Goodbye', 3: 'You say yes', 4: 'I say no'}
>>> some_dict = {key: value for key, value in some_dict.items() if value != value_to_remove}
>>> some_dict
{1: 'Hello', 2: 'Goodbye', 4: 'I say no'}

Así que probablemente quieras != en lugar de no es.

Comentarios (5)

La función items() devuelve una lista, y es esa lista la que se está iterando, así que mutar el dict en el bucle no importa aquí. Si se utiliza iteritems() en su lugar, mutar el dict en el bucle sería problemático, y lo mismo para viewitems() en Python 2.7.

No se me ocurre una forma mejor de eliminar elementos de un dict por valor.

Comentarios (0)

No hay nada malo en borrar elementos del diccionario mientras se itera, como has propuesto. Ten cuidado con que varios hilos utilicen el mismo diccionario al mismo tiempo, lo que puede dar lugar a un KeyError u otros problemas.

Por supuesto, consulte los documentos en http://docs.python.org/library/stdtypes.html#typesmapping

Comentarios (2)