[pyar] Remover elementos de una lista mientras se la recorre

Claudio Freire klaussfreire en gmail.com
Lun Dic 27 13:35:48 ART 2010


2010/12/27 Juanjo Conti <jjconti en gmail.com>

> Muchas gracias a todos.
>
> 2010/12/27 Claudio Freire <klaussfreire en gmail.com>:
> > 1) crear una copia de la lista para iterarla:
> >
> > for x in list(l):
> >     l.remove(x)
>
> Intentaba evitar esto por que la lista es muy grande, pero parece que
> no hay otra.
>
> Por otro lado comento que simplifiqué el ejemplo, y en realidad borro
> elementos según una condición.
>

Si la lista es muy grande, realmente deberías evitar .remove(), que tiene
que buscar el elemento en la lista y resulta en orden cuadrático.

Dependiendo de lo que guardes en la lista, podés ir mejorando **el
algoritmo**:

Definiendo tu condicion como una función:

def condicion(x):
   return blah

Primero, borrando por posición en vez de valor:

for x in reversed(xrange(len(l))):
   if condicion(l[x]):
      del l[x]

Eso aún tiene orden cuadrático (aunque es mucho más rápido).

No evitas generar una copia, pero suele ser casi óptimo *filtrar*:

l = filter(condicion, l)

Filtrar tiene orden lineal.

Si querés ni crear una copia ni tener orden cuadrático, y **no te importa el
orden de los elementos**, entonces podés hacer lo siguiente:

for x in reversed(xrange(len(l))):
   if condicion(l[x]):
      l[x] = l[-1]
      del l[-1]

Pues borrar el último elemento evita el costo de mover todos los elementos
siguientes para atrás (no hay elementos siguientes en del l[-1], pero sí si
hacés del l[x]).
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://listas.python.org.ar/pipermail/pyar/attachments/20101227/7cf05963/attachment.html>


More information about the pyar mailing list