我知道如果您当前正在迭代该列表,则无法从列表中删除元素。我正在尝试做的是将该列表中我不想删除的元素复制到另一个列表,然后用新列表替换原始列表。这是我的相关代码:
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添加任何标记。我无法弄清楚我做错了什么。有什么建议吗?
答案 0 :(得分: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) ]
答案 1 :(得分:0)
一个问题是,在第一次遇到应该删除的令牌后,你永远不会将removeFlag设置为False。一旦检测到应该删除的那个,它也将从列表中删除所有令牌之后的所有令牌。你需要在所有的completionHash elif中将它设置为False(并确保它们测试的状态值是唯一的可能)或者只是在for token in tokenlist
循环中立即设置它。
如果在您的测试中第一份工作在您第一次检查完成时已经完成,那么这将与描述的行为相符。
答案 2 :(得分:0)
我知道您希望删除列表中的项目而不保留它们,因此,我认为您可以执行的操作是保存与要删除的列表项目对应的数字。例如,假设我有一个数字从1到5的列表,但我只希望这个列表得到奇数,所以我想删除偶数。我要做的是设置一个带有计数器的循环,检查列表中的每个项目是否有条件(在这种情况下我会检查是否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
这对于这个问题很有效,所以我相信并希望它会帮助你。