2011-09-20 12 views
5

Estoy tratando de eliminar un diccionario de una lista si ya existe pero parece que no funciona. ¿Alguien puede ver lo que estoy haciendo mal o aconsejarme lo que debería estar haciendopython - eliminar diccionario de la lista si existe

new_dict = {'value': 'some value', 'key': 'someKey'} 
if new_dict in my_list: 
    my_list.remove(new_dict) 

new_list es una lista de diccionarios en new_dict está definitivamente en

+4

Esto funciona para mí. ¿Cómo construyes my_list? – Louis

Respuesta

7

Si new_dict es "definitivamente" en my_list, a continuación, my_list.remove(new_dict) debe hacer el truco (es decir, sin necesidad de que el if new_dict in my_list, que simplemente se ralentiza).

+3

Esto. Para estar seguro, podrías envolverlo en un 'try/except' y tratar con' ValueError's. –

1

En la mayoría de los casos, es inteligente para construir una nueva lista:

new_list = [ dd for dd in my_list if not dd is new_dict ] 

Esto es típico para un estilo de programación funcional, ya que evita los efectos secundarios. Imagine si utiliza su solución en una función o método. En la mayoría de los casos, necesita una lista modificada solo para fines internos; luego, modificar un parámetro de entrada es peligroso.

+0

¿Estás seguro de que quieres usar 'is' aquí en lugar de' == '? –

+0

Esta no es una respuesta a la pregunta. Es otra forma que no cambiará nada si lo que tiene no está funcionando para él. Y personalmente, no estoy de acuerdo con usted en que "en la mayoría de los casos es inteligente construir una nueva lista". Diría que ocasionalmente será deseado, pero casi siempre será ineficiente. –

+0

@Tim: Eso depende. Pero como la pregunta se usa "en", tienes razón, debería ser "==". – rocksportrocker

4
my_list = [1,{'value':'some value', 'key' :'somekey'}, 2, {'z':'z', 'x': 'x'}] 
new_dict = {'value':'some value', 'key' :'somekey'} 
#new_dict = {'z':'z', 'x': 'x'} 

differ = 0 
matched = 0 
for element in my_list: 
    if type(element) is types.DictType and matched != 0: 
     differ = 0 
     # check if dictionary keys match 
     if element.viewkeys() == new_dict.viewkeys(): 
      # check if dictionary values match 
      for key in element.keys(): 
       if element[key] != new_dict[key]: 
        differ = 1 
     matched = 1 

if differ != 1: 
    my_list.remove(new_dict) 

print my_list 

Funcionó para los dos diccionarios por mí.

0

Su problema puede provenir del hecho de que eliminar de una lista al iterar sobre la misma lista no es seguro. Lo que quiere hacer es algo como:

copied_list = my_list[:] 
if new_dict in copied_list: 
    my_list.remove(new_dict) 

De esta manera, itera sobre una copia de la lista y la elimina del original.

Sin embargo, puede que esta no sea la causa de su problema. Sería interesante ver:

  • la forma de construir my_list
  • lo que haces con my_list después del bucle, es decir, ¿cómo se da cuenta de su diccionario no se ha eliminado
Cuestiones relacionadas