deleting elements from a list in a for loop

Discussion in 'Python' started by flupke, Oct 29, 2004.

  1. flupke

    flupke Guest

    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
     
    flupke, Oct 29, 2004
    #1
    1. Advertisements

  2. 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 :
     
    Pierre Barbier de Reuille, Oct 29, 2004
    #2
    1. Advertisements

  3. 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 ;)
     
    Benjamin Niemann, Oct 29, 2004
    #3
  4. flupke

    flupke Guest



    Thanks,

    that works great!

    Benedict
     
    flupke, Oct 29, 2004
    #4
  5. flupke

    flupke Guest

    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
     
    flupke, Oct 29, 2004
    #5
  6. flupke

    Larry Bates Guest

    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.
     
    Larry Bates, Oct 29, 2004
    #6
    1. Advertisements

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 (here). After that, you can post your question and our members will help you out.