2

我了解如果您当前正在迭代该列表,则无法从列表中删除元素。然后我要做的是将我不想删除的列表中的元素复制到另一个列表,然后用新列表替换原始列表。这是我的相关代码:

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
                print(completionHash['Error'])

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

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

            tokenListError.append(token)
            removeFlag = True

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


    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
    time.sleep(checkInterval)

所以这一切的重点是用新列表更新 tokenList。每次循环,新任务都会完成,它们不应该被添加到 updatedTokenList 中。剩余的任务令牌将替换原始令牌列表。

这不起作用。在我第一次通过时,即使尚未完成任何任务,它也不会向 updatedTokenList 添加任何令牌。我无法弄清楚我做错了什么。有什么建议么?

4

3 回答 3

5

如果将逻辑移到函数中,这会变得容易得多:

#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 ...
    ...

现在,您可以用简单的列表推导替换您的列表:

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

请注意,我们实际上并没有替换列表。旧的列表可能仍然有对它的引用。但是,如果您想将列表替换到位,那没问题。我们只使用切片赋值:

tokenList[:] = [ token for token in tokenList if should_keep(token) ]
于 2013-05-03T01:35:40.343 回答
0

一个问题是,在 removeFlag 第一次遇到应删除的令牌后,您永远不会将其设置为 False。一旦它检测到一个应该被删除的标记,它也会从列表中删除该标记之后的所有标记。您需要在所有的 completionHash elif 中将其设置为 False(并确保它们测试的状态值是唯一的可能性),或者直接在for token in tokenlist循环中设置它。

如果在您的测试中第一个作业在您第一次检查完成时已经完成,那将与所描述的行为相匹配。

于 2013-05-03T01:32:37.380 回答
0

我了解您希望从列表中删除项目而不保留它们,因此,我认为您可以做的是保存与您要删除的列表项目相对应的数字。例如,假设我有一个数字从 1 到 5 的列表,但我只想让这个列表获取奇数,所以我想删除偶数。我要做的是设置一个带有计数器的循环,以检查列表中的每个项目的条件(在这种情况下我会检查 if myList[ItemNumber] % 2 == 0),如果是,我将设置ItemNumber为另一个列表中的项目。然后,当所有要删除的项目在这个新列表中都有它们的编号时,我会调用另一个循环来遍历这个新列表,并从另一个列表中删除新列表中包含的项目。像这样:

myList = [1, 2, 3, 4, 5]
count = 0
toBeDeleted = []
while count < len(myList):
    if myList[count] % 2 == 0:
        toBeDeleted.append(count)
    count += 1

cont2 = len(toBeDeleted)
while cont2 > 0:
    cont3 = toBeDeleted[cont2 - 1]
    myList.pop(cont3)
    cont2 -= 1

这对这个问题很有效,所以我相信并希望它对你有帮助。

于 2013-05-03T02:41:26.930 回答