deleting elements from a list in a for loop

F

flupke

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
 
P

Pierre Barbier de Reuille

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

That should work fine ...

flupke a écrit :
 
B

Benjamin Niemann

flupke said:
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

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 ;)
 
F

flupke

Pierre said:
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

That should work fine ...

flupke a écrit :


Thanks,

that works great!

Benedict
 
F

flupke

Benjamin said:
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 ;)

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
 
L

Larry Bates

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,017
Latest member
GreenAcreCBDGummiesReview

Latest Threads

Top