2012-05-19 11 views
37

Tengo una lista¿Cómo eliminar elementos de lista en un bucle for en Python?

a = ["a", "b", "c", "d", "e"] 

Quiero eliminar elementos en esta lista en un bucle, como a continuación:

for item in a: 
    print item 
    a.remove(item) 

Pero no funciona. ¿Que puedo hacer?

+1

¿Por qué necesita eliminarlos al mismo tiempo? Simplemente itere y elimine toda la lista. ¿De verdad necesita imprimir cada artículo? – jamylak

+0

Pero confío en los elementos de la lista cuando itero sobre el ciclo. Debo deshacerme del artículo inmediatamente si coincide con una condición – alwbtc

Respuesta

65

No tiene permiso para eliminar elementos de la lista mientras itera sobre ella utilizando un bucle for.

La mejor manera de volver a escribir el código depende de lo que está tratando de hacer.

Por ejemplo, el código es equivalente a:

for item in a: 
    print item 
a[:] = [] 

Como alternativa, puede utilizar un bucle while:

while a: 
    print a.pop(0) 

Estoy tratando de eliminar elementos si coinciden con una condición . Luego voy al siguiente artículo.

Se puede copiar cada elemento que hace igualar la condición en una segunda lista:

result = [] 
for item in a: 
    if condition: 
    result.append(item) 
a = result 

Como alternativa, se puede usar filter o una lista por comprensión y asignar el resultado a a:

a = filter(lambda item:... , a) 

o

a = [item for item in a if ...] 

donde ... corresponde a la condición que necesita comprobar.

+0

Estoy tratando de eliminar elementos si coinciden con una condición. Luego voy al siguiente artículo. – alwbtc

+0

@alwbtc: Consulte la respuesta actualizada – NPE

+6

"No está permitido", seguro que sí. Python no se queja de ti, solo da un resultado levemente diferente de lo que la gente podría esperar. – lvc

2

¿Qué le parece crear una nueva lista y agregar los elementos que desea a esa nueva lista. No se puede quitar elementos, mientras iteración a través de una lista

28

iterar a través de una copia del bucle:

>>> a = ["a", "b", "c", "d", "e"] 
>>> for item in a[:]: 
    print item 
    if item == "b": 
     a.remove(item) 

a 
b 
c 
d 
e 
>>> print a 
['a', 'c', 'd', 'e'] 
+0

Un problema con esto y con los enfoques de OP es que pueden descomponerse si hay varios elementos que se pueden comparar igual. – NPE

+0

¡Impresionante! ¡Esta funciona para mí! –

+3

@NPE Supongo que depende de lo que espera que suceda. Si espera que el código elimine todas las instancias de "b" en la lista, entonces no debería romperse como [list.remove] (https://docs.python.org/2/tutorial/datastructures.html#more- on-lists) elimina solo un elemento. – vikki

-5

función Quitar quita el primer elemento de la lista (elemento de índice de 0 ª). En la primera iteración de su bucle for comienza con el número de índice 0, imprímalo. A medida que avanza al índice número 1, ya no tiene 'a' en la ubicación del índice 0, sino que tiene 'b' en su lugar. Entonces lo que obtienes será 'c'. Así que esta pieza de código imprimirá los elementos de la lista solo con números índices.

+2

No, no es así. 'mylist.remove (item)' elimina la primera instancia de 'item' en' mylist' - vea la [documentation] (http://docs.python.org/tutorial/datastructures.html). –

8

Como han dicho otras respuestas, la mejor manera de hacerlo es haciendo una nueva lista: itere sobre una copia o construya una lista con solo los elementos que desee y asígnela a la misma variable. La diferencia entre estos depende de su caso de uso, ya que afectan a otras variables para la lista original de manera diferente (o, más bien, el primero los afecta, el segundo no).

Si una copia no es una opción por alguna razón, tiene otra opción que depende de la comprensión de por qué modificar una lista que está iterando se rompe.La iteración de lista funciona haciendo un seguimiento de un índice, incrementándolo cada vez que pasa el ciclo hasta que cae al final de la lista. Por lo tanto, si elimina en (o antes) el índice actual, todo desde ese punto hasta el final cambia un punto a la izquierda. Pero el iterador no sabe nada al respecto y omite de manera efectiva el siguiente elemento, ya que ahora está en el índice actual en lugar de en el siguiente. Sin embargo, al eliminar elementos que son después de, el índice actual no afecta las cosas.

Esto implica que si repite la lista al revés, si elimina un elemento en el índice actual, todo lo que está a la derecha se desplaza a la izquierda, pero eso no importa, ya que ya ha tratado con todos los elementos a la derecha de la posición actual, y te mueves hacia la izquierda: el siguiente elemento a la izquierda no se ve afectado por el cambio, por lo que el iterador te da el elemento que esperas.

TL; DR:

>>> a = list(range(5)) 
>>> for b in reversed(a): 
    if b == 3: 
     a.remove(b) 
>>> a 
[0, 1, 2, 4] 

Sin embargo, hacer una copia suele ser mejor en términos de hacer su código fácil de leer. Solo menciono esta posibilidad para completar.

1
import copy 

a = ["a", "b", "c", "d", "e"] 

b = copy.copy(a) 

for item in a: 
    print item 
    b.remove(item) 
a = copy.copy(b) 

Obras: Para evitar el cambio de la lista que está iterando, se hace una copia de a, iterar sobre ella y eliminar los elementos de b. A continuación, copie b (la copia modificada) nuevamente en a.

0

Probablemente un poco tarde para responder pero me he encontrado este hilo y yo había creado mi propio código para ello previamente ...

list = [1,2,3,4,5] 
    deleteList = [] 
    processNo = 0 
    for item in list: 
     if condition: 
      print item 
      deleteList.insert(0, processNo) 
     processNo += 1 

    if len(deleteList) > 0: 
     for item in deleteList: 
      del list[item] 

puede ser un largo camino de hacerlo, pero parece funcionar bien. Creo una segunda lista que solo contiene números que se relacionan con el elemento de la lista para eliminar. Tenga en cuenta que la "inserción" inserta el número de elemento de la lista en la posición 0 y empuja el resto, por lo que al eliminar los elementos, la lista se elimina desde el número más alto hasta el número más bajo para que la lista permanezca en secuencia.

Cuestiones relacionadas