Connecting Tech Pros Worldwide Help | Site Map

deleting elements from a list in a for loop

flupke
Guest
 
Posts: n/a
#1: Jul 18 '05
Hi,

i'm having trouble with deleting elements from a list in a for loop

============== test program ==============
el = [ "one", "two", "three", "four" ]
print "**** Start ****"
print "List = %s " % el
index = 0
for line in el:
print " el = %s " % line
if ( index == 1 ):
print " deleting %s " % line
del el[index]
else:
index += 1
print "**** After delete ****"
print "List = %s " % el

print "**** After adding two ****"
el.append("two")
print "List = %s " % el
============== test program ==============

This is the output that i get
**** Start ****
List = ['one', 'two', 'three', 'four']
el = one
el = two
deleting two
el = four
deleting four
**** After delete ****
List = ['one', 'four']
**** After adding two ****
List = ['one', 'four', 'two']

After deleting it doesn't go to element "three". Why is that?
How can i safely delete from a list?
The reason is that i'm currently making an application to manage my
links. I write a couple of links to the screen in a listbox (wxPython)
and thus i delete those links that appear on screen from the list
because people will be able to edit them.
Then when they move to another link section, i write the content of the
listbox back to the list. But as i've illustrated in the small example
my coding is flawed.

Thanks,
Benedict
Pierre Barbier de Reuille
Guest
 
Posts: n/a
#2: Jul 18 '05

re: deleting elements from a list in a for loop


Hi !

Indeed, you cannot erase elements in a list you're iterating on !
a possibility could be :

to_delete = []
for i in xrange(len(el)):
if condition:
to_delete.insert(0, i)
for i in to_delete:
del el[i]

That should work fine ...

flupke a écrit :[color=blue]
> Hi,
>
> i'm having trouble with deleting elements from a list in a for loop
>
> ============== test program ==============
> el = [ "one", "two", "three", "four" ]
> print "**** Start ****"
> print "List = %s " % el
> index = 0
> for line in el:
> print " el = %s " % line
> if ( index == 1 ):
> print " deleting %s " % line
> del el[index]
> else:
> index += 1
> print "**** After delete ****"
> print "List = %s " % el
>
> print "**** After adding two ****"
> el.append("two")
> print "List = %s " % el
> ============== test program ==============
>
> This is the output that i get
> **** Start ****
> List = ['one', 'two', 'three', 'four']
> el = one
> el = two
> deleting two
> el = four
> deleting four
> **** After delete ****
> List = ['one', 'four']
> **** After adding two ****
> List = ['one', 'four', 'two']
>
> After deleting it doesn't go to element "three". Why is that?
> How can i safely delete from a list?
> The reason is that i'm currently making an application to manage my
> links. I write a couple of links to the screen in a listbox (wxPython)
> and thus i delete those links that appear on screen from the list
> because people will be able to edit them.
> Then when they move to another link section, i write the content of the
> listbox back to the list. But as i've illustrated in the small example
> my coding is flawed.
>
> Thanks,
> Benedict[/color]
Benjamin Niemann
Guest
 
Posts: n/a
#3: Jul 18 '05

re: deleting elements from a list in a for loop


flupke wrote:[color=blue]
> Hi,
>
> i'm having trouble with deleting elements from a list in a for loop
>
> ============== test program ==============
> el = [ "one", "two", "three", "four" ]
> print "**** Start ****"
> print "List = %s " % el
> index = 0
> for line in el:
> print " el = %s " % line
> if ( index == 1 ):
> print " deleting %s " % line
> del el[index]
> else:
> index += 1
> print "**** After delete ****"
> print "List = %s " % el
>
> print "**** After adding two ****"
> el.append("two")
> print "List = %s " % el
> ============== test program ==============
>
> This is the output that i get
> **** Start ****
> List = ['one', 'two', 'three', 'four']
> el = one
> el = two
> deleting two
> el = four
> deleting four
> **** After delete ****
> List = ['one', 'four']
> **** After adding two ****
> List = ['one', 'four', 'two']
>
> After deleting it doesn't go to element "three". Why is that?
> How can i safely delete from a list?
> The reason is that i'm currently making an application to manage my
> links. I write a couple of links to the screen in a listbox (wxPython)
> and thus i delete those links that appear on screen from the list
> because people will be able to edit them.
> Then when they move to another link section, i write the content of the
> listbox back to the list. But as i've illustrated in the small example
> my coding is flawed.
>
> Thanks,
> Benedict[/color]

If it doesn't matter in which order you scan the list:

for idx in xrange(len(el), -1, -1):
element = el[idx]
if ....:
del el[idx]

By running from end to start of the list, a "del" won't affect later iterations
of the loop.
Generally: you shouldn't modify a list while doing a "for a in el:" - this just
causes confusion (as you've already seen ;)
flupke
Guest
 
Posts: n/a
#4: Jul 18 '05

re: deleting elements from a list in a for loop


Pierre Barbier de Reuille wrote:
[color=blue]
> Hi !
>
> Indeed, you cannot erase elements in a list you're iterating on !
> a possibility could be :
>
> to_delete = []
> for i in xrange(len(el)):
> if condition:
> to_delete.insert(0, i)
> for i in to_delete:
> del el[i]
>
> That should work fine ...
>
> flupke a écrit :[/color]

Thanks,

that works great!

Benedict
flupke
Guest
 
Posts: n/a
#5: Jul 18 '05

re: deleting elements from a list in a for loop


Benjamin Niemann wrote:[color=blue]
> If it doesn't matter in which order you scan the list:
>
> for idx in xrange(len(el), -1, -1):
> element = el[idx]
> if ....:
> del el[idx]
>
> By running from end to start of the list, a "del" won't affect later
> iterations of the loop.
> Generally: you shouldn't modify a list while doing a "for a in el:" -
> this just causes confusion (as you've already seen ;)[/color]

Scan order doesn't matter so i could also use this sollution.
The for line should be "for idx in xrange(len(el)-1, -1, -1):"
for it to work.

Any, also a great sollution, thanks!

Benedict
Larry Bates
Guest
 
Posts: n/a
#6: Jul 18 '05

re: deleting elements from a list in a for loop


When I encounter this type of requirement I almost always find
that it is much easier and clearer to use list comprehensions
or slicing to create a new lists (depending on your needs):

el=[ "one", "two", "three", "four" ]

index=0
el=[line for line in el if line == el[index]]

or if you want the non-matching elements

el2=[line for line in el if line != el[index]]

Larry Bates
Syscon, Inc.


flupke wrote:[color=blue]
> Hi,
>
> i'm having trouble with deleting elements from a list in a for loop
>
> ============== test program ==============
> el = [ "one", "two", "three", "four" ]
> print "**** Start ****"
> print "List = %s " % el
> index = 0
> for line in el:
> print " el = %s " % line
> if ( index == 1 ):
> print " deleting %s " % line
> del el[index]
> else:
> index += 1
> print "**** After delete ****"
> print "List = %s " % el
>
> print "**** After adding two ****"
> el.append("two")
> print "List = %s " % el
> ============== test program ==============
>
> This is the output that i get
> **** Start ****
> List = ['one', 'two', 'three', 'four']
> el = one
> el = two
> deleting two
> el = four
> deleting four
> **** After delete ****
> List = ['one', 'four']
> **** After adding two ****
> List = ['one', 'four', 'two']
>
> After deleting it doesn't go to element "three". Why is that?
> How can i safely delete from a list?
> The reason is that i'm currently making an application to manage my
> links. I write a couple of links to the screen in a listbox (wxPython)
> and thus i delete those links that appear on screen from the list
> because people will be able to edit them.
> Then when they move to another link section, i write the content of the
> listbox back to the list. But as i've illustrated in the small example
> my coding is flawed.
>
> Thanks,
> Benedict[/color]
Closed Thread