Weird behavior removing elements from a list in a loop in Python -
i understand can't remove element list if iterating on list. i'm trying copy elements list not wish remove list, , replacing original list new list. here's relevant code:
while len(tokenlist) > 0: # loop through tokenlist list # reset updated token list , remove flag updatedtokenlist = [] removeflag = false token in tokenlist: completionhash = aciserver.checktaskforcompletion(token) # if completion hash not empty hash, parse information if completionhash != {}: # if find task has completed, remove list if completionhash['status'] == 'finished' , completionhash['error'] == '': # task completed successfully, remove token list removeflag = true elif completionhash['status'] == 'running' , completionhash['error'] == '': # task must still running print('task ' + completionhash['type'] + ' ' + token + ' has been running ' + completionhash['runtime'] + ' seconds.') elif completionhash['status'] == 'queued': # task in queue print('task ' + completionhash['type'] + ' ' + token + ' queued in position ' + completionhash['queueposition']) elif completionhash['status'] == 'not_found': # did not find task token, possible task hasn't been added yet print(completionhash['error']) # if task still running, no change token list have occured else: # because server got rid of token after task completed print('completion hash empty, went wrong.') tokenlisterror.append(token) removeflag = true if not removeflag: print('appending token updatedtokenlist') updatedtokenlist.append(token) print('length of tokenlist after removal loop: ' + str(len(updatedtokenlist))) # wait time, proportional number of tasks left checkinterval = len(updatedtokenlist) * checkintervalmultiplier print('waiting ' + str(checkinterval) + ' seconds before checking again...') print('tokens remaining: ' + str(len(updatedtokenlist))) # replace original token list updated token list tokenlist = updatedtokenlist # wait while based on how many tokens remain time.sleep(checkinterval)
so point of update tokenlist new list. every time through loop, new tasks have finished , should not added updatedtokenlist. remaining task tokens , replaces original token list.
this not work. on first pass through, not add tokens updatedtokenlist though no tasks have yet completed. cannot figure out doing wrong. suggestions?
this gets lot easier if move logic function:
#this function should have more descriptive name follows #project's api. def should_keep(token): """returns true if token should kept""" #do other stuff here. possibly print stuff or whatever ... ...
now, can replace list simple list comprehension:
tokenlist = [ token token in tokenlist if should_keep(token) ]
note haven't actually replaced list. old list still presumably have references hanging around. if want replace list in place though, it's no problem. use slice assignment:
tokenlist[:] = [ token token in tokenlist if should_keep(token) ]
Comments
Post a Comment