[pyar] Remover elementos de una lista mientras se la recorre
Claudio Freire
klaussfreire en gmail.com
Lun Dic 27 13:14:29 ART 2010
2010/12/27 Ricardo Armas <rarmas en gmail.com>
> 2010/12/27 Juanjo Conti <jjconti en gmail.com>:
> > Lista, les comento un comportamiento que me llamó la atención:
> >
> >>>> l = range(3)
> >>>> for x in l:
> > ... l.remove(x)
> > ...
> >>>> l
> > [1]
> >
> > Por qué queda un elemento en la lista?
> Ya sé, es así, en la primera se elimina el 0 así que el primer
> elemento pasa a ser el 1, el for en el segundo ciclo pasa al segundo
> elemento que es el 2, por eso queda el 1 en la lista.
>
Exacto, el iterador de listas es un contador.
for x in l:
...
equivale a
ix = 0
while ix < len(l):
x = l[ix]
ix += 1
...
Luego, si seguís la ejecución de este último código (que es equivalente),
ves por qué queda el 1.
Sabiendo esto, tenés dos opciones:
1) crear una copia de la lista para iterarla:
for x in list(l):
l.remove(x)
2) iterar en reverso
for x in reverse(l):
l.remove(x)
Ojo que 2 funciona sólo porque remove() **EN ESTE CASO** no modifica la
parte futura del iterador (o sea, los índices que falta iterar), sólo
modifica lo que el iterador ya recorrió, y no cambia los índices de lo que
falta recorrer.
Pero otro caso podría funcionar mal.
Por ejemplo:
>>> l = [1,2,3,1,2,3]
>>> for x in reversed(l):
... print x
... l.remove(x)
... print l
...
3
[1, 2, 1, 2, 3]
3
[1, 2, 1, 2]
2
[1, 1, 2]
2
[1, 1]
1
[1]
1
[]
La lista termina vacía, pero se ve claramente que el procedimiento no fue
como uno esperaba. Me cuesta encontrar un ejemplo donde la lista no quede
vacía, pero seguro hay alguno.
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://listas.python.org.ar/pipermail/pyar/attachments/20101227/92ca0a75/attachment.html>
More information about the pyar
mailing list