deleting items within a for loop - mutable indices

James Moughan moughanj at tcd.ie
Sat Apr 24 04:06:26 EDT 2004


SnuSnu <snusnu at tiscali.co.uk> wrote in message news:<4089cb21$1_2 at mk-nntp-2.news.uk.tiscali.com>...
> Okay - here's a (probably) really easy question:
> 
> I can't do the following, so what's the best way to handle this
> case of wanting to delete within a loop?
> 
> x = [0,1,2,3,4,5,6,7,8]
> deletion_list = [2,7,8]
> 
> for i in deletion_list:
>   del x[i]
> 
> This obviously doesn't work because the list keeps changing
> each time I delete something, so the indices are no longer valid
> after the first delete (so I get an IndexError on teh last delete).
> 
> My hack is to do this first (which makes sure that the higher indices 
> are deleted first), but this is not very elegant or quick:
> 
> deletion_list.sort()
> deletion_list.reverse()
> # BTW: It's a shame I can't do deletion_list.sort().reverse()
> 
> Is there a simple solution?
> 
> (It would be nice to do something like
>   del x[2,7,8]           # or..
>   del [*deletion_list]
> )
> 
> Thanks.

Eh, do you want to delete the elements in the deletion list from x, or
delete the elements in x which are at the location indicated in the
deletion list?  Your example doesn't differentiate.

Anyhow, this is advice from a newbie :-) but in the first case

x = [y for y in x if not y in deletion_list]

works well enough.

otherwise

tmp = [x[i] for i in range(len(x)) if not i in deletion_list]
x = tmp

you could speed either up for largish lists with hashing;

dict = {}
for d in deletion_list:
    dict[d] = 1
tmp = [x[i] for i in range(len(x)) if not dict.has_key(i)]
x = tmp

alternatively you could make it linear in time for the number of
deletion elements, but the performance hit from creating a bunch of
lists hurts a bit too much, unless you don't care about order.  Which
I'm guessing you do.

Jam



More information about the Python-list mailing list