[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [pygame] Iterate over list and delete



I think what you're looking for is this:

my_list = [x for x in my_list if not need_to_delete(x)]

On Sun, May 20, 2018, 16:28 Irv Kalb <Irv@xxxxxxxxxxxxxx> wrote:
I am building a game where I am keeping track of many objects in a list (let's just call it "myList".  In every "frame" of my game I need to see if any objects need to be removed from myList.

I know that this code:

for item in myList:
    if needsToBeDeleted(item):
         myList.remove(item)

does not work correctly because it affects the order of list while I am iterating over it.  (Specifically, if there are two elements in a row that should be removed, the first one is removed, but the second one is skipped over.)

I have looked at many different solutions, and have found a number of different approaches, but none them seem elegant.  Here are ones that work:

1)  Build a list of indices in reverse order (  [n - 1, n -2, n - 3, ... 0] )
     Iterate over this list
          if the element at that index needs to be deleted,
                pop the element at this index

    (untested, but should work)

     indexList = list(range(0, n - 1))
     indexList.reverse()

     for index in indexList:
          if needsToBeDeleted(myList[index]):
                myList.pop(index)

    I believe this will work, but it looks very clunky.


2)  Create a tempList that starts off empty.
     Iterate through my original list.
        If an element does NOT need to be deleted, append it to the tempList. 
     Reassign the myList to the tempList
     Set the tempList to None (or delete it)

     tempList = []
     for item in myList:
         if not needsToBeDeleted(item):
             tempList.append(item)
      myList = tempList
      tempList = None

     Seems OK, but again, seems like kind of a kludge.

3)  Iterate through a copy of the list:

     for item in myList[:]:
         if needsToBeDeleted(item):
             myList.remove(item)

      This does work, but I would guess it might be slow for long lists (since it first has to duplicate a list, then when it wants to delete an element, 'remove' must search through the list to find the matching element before deleting it).  Also, it would be tricky to explain to students, because I am iterating through a copy of a list, but deleting elements from the original list.


Does anyone have an easier, more clear, reusable approach?

If not, any thoughts on which of these three approach would be most efficient and clear?  I don't have a favorite yet.

Thanks,

Irv