Re: Borrar elementos de una lista por índices

Alexis Roda Villalonga alexis.roda.villalonga en gmail.com
Dom Jul 2 16:15:28 CEST 2006


2006/7/2, Arnau Sanchez <arnau en ehas.org>:
> Buenas,
>
> Ya son varias las veces que me he encontrado con que necesitaba borrar
> elementos de una lista según su índice, no su valor. ¿Cuál creéis que
> sería la mejor forma de hacerlo?
>
> Para empezar, la más evidente:
>
> # lista
> aborrar = [1,4,8]
> salida = [lista[x] for x in range(len(lista)) if x not in aborrar]
>
> Problema: hay que recorrer toda la lista, y además crear una nueva, no
> parece muy eficiente.

Crear una nueva lista es eficiente cuando lo que necesitas es crear
una nueva lista.

El problema aquí es que recorre toda la lista 'aborrar' para
determinar si un elemento 'x' no se borra, no que tenga que recorrer
la lista 'lista' una vez (deberás hacerlo de una forma u otra si
necesitas copiar la lista). Podrias mejorarlo convirtiendo 'aborrar'
en un diccionario, tiempo de consulta constante.

d=dict.fromkeys(aborrar)
l = [ v for i, v in enumerate(lista) if i not in d ]

> ¿Y si tratáramos de hacerlo "in-place"? El "del" sólo borra elementos
> individuales o slices, así que habría que hacer un bucle. Pero entonces
> nos encontramos que, de una iteración a otra, la lista ha perdido un
> elemento, por lo que habría que hacer una corrección, tal que así:
>
> # lista
> aborrar = [1,4,8]
> for n, ab in enumerate(aborrar):
>          del lista[ab-n]
>
> que a primera vista es poco elegante.

Para que la corrección funcione 'aborrar' debe estar ordenado
crecientemente. Si lo ordenas decrecientemente (borras de derecha a
izquierda) no necesitas la corrección:

aborrar.sort(lambda a,b : cmp(b, a))
for i in aborrar :
   del lista[i]



Saludos




Más información sobre la lista de distribución Python-es