cómo modificar correctamente el iterador de un bucle en python desde dentro del bucle

lo que básicamente necesito es verificar todos los elementos de una lista y si algunos criterios se ajustan, quiero eliminarlos de la lista.

Así, por ejemplo, digamos que

list=['a','b','c','d','e'] 

Básicamente quiero escribir (en principio y no el código real que bash implementar)

Si un elemento de la lista es ‘b’ o ‘c’, elimínelo de la lista y tome el siguiente.

Pero

 for s in list: if s=='b' or s=='c': list.remove(s) 

falla porque cuando se elimina ‘b’ el bucle toma ‘d’ y no ‘c’ como el siguiente elemento. Entonces, ¿hay una manera de hacerlo más rápido que almacenar los elementos en una lista separada y eliminarlos después?

Gracias.

La forma más fácil es usar una copia de la lista; se puede hacer con una porción que se extiende “desde el principio” hasta el “final” de la lista, como esto:

 for s in list[:]: if s=='b' or s=='c': list.remove(s) 

Usted ha considerado esto, y esto es lo suficientemente simple como para estar en su código, a menos que esta lista sea realmente grande, y en una parte crítica del código (como, en el bucle principal de un juego de acción). En ese caso, a veces uso el siguiente idioma:

 to_remove = [] for index, s in enumerate(list): if s == "b" or s == "c": to_remove.append(index) for index in reversed(to_remove): del list[index] 

Por supuesto, puedes recurrir a un bucle while en su lugar:

 index = 0 while index < len(list): if s == "b" or s == "c": del list[index] continue index += 1 

Es mejor no reinventar cosas que ya están disponibles. Utilice las funciones de filtro y lambda en estos casos. Es más python y se ve más limpio.

 filter(lambda x:x not in ['b','c'],['a','b','c','d','e']) 

alternativamente puedes usar la lista de comprensión

 [x for x in ['a','b','c','d','e'] if x not in ['b','c']] 

Esto es exactamente para lo que está diseñado itertols.ifilter.

 from itertools import ifilter ifilter(lambda x: x not in ['b', 'c'], ['a', 'b', 'c', 'd', 'e']) 

le devolverá un generador para su lista. Si realmente necesita una lista, puede crearla utilizando una de las técnicas estándar para convertir un generador en una lista:

 list(ifilter(lambda x: x not in ['b', 'c'], ['a', 'b', 'c', 'd', 'e'])) 

o

 [x for x in ifilter(lambda x: x not in ['b', 'c'], ['a', 'b', 'c', 'd', 'e'])] 

Si está de acuerdo con crear una copia de la lista, puede hacerlo de esta manera ( comprensión de la lista ):

 [s for s in list if s != 'b' and s != 'c']