Weird behavior removing elements from a list in a loop in Python

I understand that you can't remove an element from a list if you are currently iterating over that list. What I'm trying to do then is to copy elements from that list that I do NOT wish to remove to another list, and then replacing the original list with the new list. Here's my relevant code:

while len(tokenList) > 0:
    # loop through the tokenList list

    # reset the updated token list and the remove flag
    updatedTokenList = []
    removeFlag = False

    for token in tokenList:

        completionHash = aciServer.checkTaskForCompletion(token)

        # If the completion hash is not the empty hash, parse the information
        if completionHash != {}:
            # if we find that a task has completed, remove it from the list
            if completionHash['Status'] == 'FINISHED' and completionHash['Error'] == '':
                # The task completed successfully, remove the token from the list
                removeFlag = True

            elif completionHash['Status'] == 'RUNNING' and completionHash['Error'] == '':
                # The task must still be running
                print('Task ' + completionHash['Type'] + ' ' + token + ' has been running for ' + completionHash['Runtime'] + ' seconds.')

            elif completionHash['Status'] == 'queued':
                # The task is in the queue
                print('Task ' + completionHash['Type'] + ' ' + token + ' is queued in position ' + completionHash['QueuePosition'])

            elif completionHash['Status'] == 'not_found':
                # Did not find a task with this token, possible the task hasn't been added yet

            # if the task is still running, no change to the token list will have occured

            # This is probably because the server got rid of the token after the task completed
            print('Completion hash is empty, something went wrong.')

            removeFlag = True

        if not removeFlag:
            print('appending token to updatedTokenList')

    print('length of tokenList after removal loop: ' + str(len(updatedTokenList)))

    # wait some time, proportional to the number of tasks left
    checkInterval = len(updatedTokenList) * checkIntervalMultiplier

    print('Waiting ' + str(checkInterval) + ' seconds before checking again...')
    print('Tokens remaining: ' + str(len(updatedTokenList)))

    # replace the original token list with the updated token list
    tokenList = updatedTokenList

    # wait a while based on how many tokens remain

So point of all this is to update the tokenList with new list. Every time through the loop, new tasks will have finished and they should NOT be added to the updatedTokenList. The remaining task tokens will and this replaces the original token list.

This does not work. On my first pass through, it does not add any tokens to the updatedTokenList even though no tasks have yet completed. I cannot figure out what I am doing wrong. Any suggestions?


This gets a lot easier if you move the logic into a function:

#This function should have a more descriptive name that follows your 
#project's API.
def should_keep(token):
    """returns True if the token should be kept"""
    #do other stuff here.  Possibly print stuff or whatever ...

Now, you can replace your list with a simple list comprehension:

tokenList = [ token for token in tokenList if should_keep(token) ]

Note that we haven't actually replaced the list. The old list could still presumably have references to it hanging around. If you want to replace the list in place though, it's no problem. We just use slice assignment:

tokenList[:] = [ token for token in tokenList if should_keep(token) ]

Need Your Help

Set a post to 'pending' if it get more then 3 reports in wordpress

php wordpress

I am using wp user frontend, and I have also downloaded a plugin called 'WP-Reportpost'.

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.