Sé eliminar una entrada, 'clave' de mi diccionario d
, de manera segura, usted hace:
if d.has_key('key'):
del d['key']
Sin embargo, necesito eliminar varias entradas del diccionario de forma segura. Estaba pensando en definir las entradas en una tupla, ya que tendré que hacerlo más de una vez.
entitiesToREmove = ('a', 'b', 'c')
for x in entitiesToRemove:
if d.has_key(x):
del d[x]
Sin embargo, me preguntaba si hay una manera más inteligente de hacer esto.
python
dictionary
dublintech
fuente
fuente
key in d
es más Pythonic qued.has_key(key)
stackoverflow.com/questions/1323410/has-key-or-infor x in set(d) & entities_to_remove: del d[x]
. Esto probablemente solo será más eficiente sientities_to_remove
es "grande".Respuestas:
¿Por qué no así?
Mattbornski proporcionó una versión más compacta con dict.pop ()
fuente
del dict['key1'], dict['key2'], dict['key3']
for key in set(the_dict) & entries:
y omitir lakey in dict
prueba.fuente
dict.pop()
elimina la necesidad de pruebas de existencia clave. Excelente..pop()
es malo y antipático, y preferiría la respuesta aceptada sobre esta.setdefault
. Si se implementa correctamente (y estoy seguro de que lo es), solo realiza una búsqueda en el mapa hash que esdict
, en lugar de dos.Usando comprensiones Dict
donde key1 y key2 son para ser eliminado.
En el ejemplo a continuación, las claves "b" y "c" se eliminarán y se mantendrán en una lista de claves.
fuente
O(n)
. Toda la operación esO(mn)
dóndem
está el número de claves en el dict yn
el número de claves en la lista. Sugiero usar un conjunto en su{key1, key2}
lugar, si es posible.una solución está usando
map
yfilter
funcionespitón 2
pitón 3
usted obtiene:
fuente
>>> d={"a":1,"b":2,"c":3} >>> l=("a","b","d") >>> map(d.__delitem__, filter(d.__contains__,l)) <map object at 0x10579b9e8> >>> print(d) {'a': 1, 'b': 2, 'c': 3}
list(map(d.__delitem__,filter(d.__contains__,l)))
.... en python 3.4 la función de mapa devuelve un iteradordeque(map(...), maxlen=0)
para evitar construir una lista de valores None; primera importación confrom collections import deque
Si también necesita recuperar los valores de las claves que está eliminando, esta sería una muy buena manera de hacerlo:
Por supuesto, aún podría hacer esto solo para eliminar las claves
d
, pero estaría creando innecesariamente la lista de valores con la comprensión de la lista. Tampoco es un poco claro usar una lista de comprensión solo para el efecto secundario de la función.fuente
valuesRemoved = dict((k, d.pop(k, None)) for k in entitiesToRemove)
y así sucesivamente.Encontró una solución con
pop
ymap
El resultado de esto:
He respondido esta pregunta tan tarde solo porque creo que ayudará en el futuro si alguien busca lo mismo. Y esto podría ayudar.
Actualizar
El código anterior arrojará un error si no existe una clave en el dict.
salida:
fuente
keys
no existed
; primero debe filtrarla.No tengo ningún problema con ninguna de las respuestas existentes, pero me sorprendió no encontrar esta solución:
Nota: me topé con esta pregunta desde aquí . Y mi respuesta está relacionada con esta respuesta .
fuente
Por qué no:
No sé a qué te refieres con "forma más inteligente". Seguramente hay otras formas, tal vez con la comprensión del diccionario:
fuente
en línea
fuente
Algunas pruebas de tiempo para cpython 3 muestran que un bucle simple es la forma más rápida y es bastante legible. Agregar una función tampoco causa mucha sobrecarga:
Resultados de timeit (10k iteraciones):
all(x.pop(v) for v in r) # 0.85
all(map(x.pop, r)) # 0.60
list(map(x.pop, r)) # 0.70
all(map(x.__delitem__, r)) # 0.44
del_all(x, r) # 0.40
<inline for loop>(x, r) # 0.35
Para iteraciones pequeñas, hacer eso 'en línea' fue un poco más rápido, debido a la sobrecarga de la llamada a la función. Pero
del_all
es sin pelusa, reutilizable y más rápido que todas las construcciones de mapeo y comprensión de Python.fuente
Creo que usar el hecho de que las claves se pueden tratar como un conjunto es la mejor manera si estás en Python 3:
Ejemplo:
fuente
Sería bueno tener un soporte completo para los métodos establecidos para los diccionarios (y no el lío impuro que estamos teniendo con Python 3.9) para que simplemente pueda "eliminar" un conjunto de claves. Sin embargo, mientras ese no sea el caso, y tenga un diccionario grande con una cantidad potencialmente grande de claves para eliminar, es posible que desee saber sobre el rendimiento. Entonces, he creado un código que crea algo lo suficientemente grande como para realizar comparaciones significativas: una matriz de 100,000 x 1000, por lo que 10,000,00 artículos en total.
10 millones de artículos o más no es inusual en algunos entornos. Comparando los dos métodos en mi máquina local, veo una ligera mejora al usarlo
map
ypop
, presumiblemente debido a menos llamadas de función, pero ambas toman alrededor de 2.5s en mi máquina. Pero esto palidece en comparación con el tiempo requerido para crear el diccionario en primer lugar (55s), o incluir verificaciones dentro del ciclo. Si esto es probable, es mejor crear un conjunto que sea una intersección de las teclas del diccionario y su filtro:keys = cells.keys() & keys
En resumen:
del
ya está muy optimizado, así que no se preocupe por usarlo.fuente
Llego tarde a esta discusión, pero para cualquier otra persona. Una solución puede ser crear una lista de claves como tal.
Luego use pop () en una lista de comprensión, o for loop, para iterar sobre las teclas y pop una a la vez como tal.
El 'n / a' es en caso de que la clave no exista, se debe devolver un valor predeterminado.
fuente
new_dictionary
se parece mucho a una lista;)