0

I feel like this should be a pretty simple process but for some reason I cannot get it to work.

Goal: Loop through a list of objects and if they match a condition remove it.

Issue: This works until it needs to remove all objects from the list. It will not remove the last item.

Example (clearly simplified by same results):

def some_function(val): return True on_shift2 = ['user1', 'user2', 'user3'] print("MY ON SHIFT2", on_shift2) for idx, val in enumerate(on_shift2): print(f"Index: {idx} & Value: {val}") if len(on_shift2) == 1: del (on_shift2) # remove the whole list else: check_user = some_function(val) # function to check if user is in list and if so return true if check_user: on_shift2.remove(val) # Also tried the following # del on_shift[idx] # Same result # on_shift.pop(idx) # Same result print("MY ON SHIFT2", on_shift2) 

Results:

MY ON SHIFT2 ['user1', 'user2', 'user3'] Index: 0 & Value: user1 Index: 1 & Value: user3 MY ON SHIFT2 ['user2'] 

Now the really odd part here is no matter what is in the list, it always seems to keem the middle item (i.e. user2). If i changed those values to chicken, horse, dog - the remaining item would be horse. Not sure if that's important but thought i would bring it up.

Also, no matter the which method i choose to remove the the items from the list (pop, remove or del), the 3rd (or last) item never gets removed if they all return true from "some_function()".

Also when looping through the if condition on the len(on_shift) never does equal 1, it always stops at 2. Never makes it to the 3rd (or last) object if the all return true from "some_fuction()", so my if statement to delete the list never happens.

If i print the val for the loop without removing anything from the list, all 3 names show up. I have to be doing something silly here.

Thoughts?

6
  • 3
    you should not remove from a list while iterating, if you must do so , then for idx, val in enumerate(on_shift2.copy()) copy and then delete, your if condition if len(on_shift2) == 1 is not needed anymore Commented Jun 8, 2021 at 2:37
  • I'm getting a different error: NameError: name 'on_shift2' is not defined Commented Jun 8, 2021 at 2:39
  • try without if check_user: line and see what happens. I guess the problem is in this line it returns false sometimes and all items do not get deleted. Commented Jun 8, 2021 at 2:41
  • 1
    @phython_user thank you for the quick reply. This is what i needed. If you want to set this as an answer ill mark it as correct. @David I get that error when i use .copy() and leave the code the same as the list gets removed in the if len(on_shift2) clause. Commented Jun 8, 2021 at 2:43
  • @Sudipto at times what you are saying is true and that part was working fine, i just couldn't figure out how to get it to remove all them when it was 100% true. Commented Jun 8, 2021 at 2:44

1 Answer 1

1

You should not modify a list while iterating over it, but if you must do so, then you need to a make a copy of the list and iterate over the copy, but delete the elements from the original list.

def some_function(val): return True on_shift2 = ['user1', 'user2', 'user3'] print("MY ON SHIFT2", on_shift2) for idx, val in enumerate(on_shift2.copy()): # copy here print(f"Index: {idx} & Value: {val}") check_user = some_function(val) # function to check if user is in list and if so return true if check_user: on_shift2.remove(val) # delete in original print("MY ON SHIFT2", on_shift2) 

Output

MY ON SHIFT2 ['user1', 'user2', 'user3'] Index: 0 & Value: user1 Index: 1 & Value: user2 Index: 2 & Value: user3 MY ON SHIFT2 [] 

This is actually slower, a better alternative would be to add only those you need to a different list.

on_shift2_new = [i for i in on_shift2 if not some_function(i)] 
Sign up to request clarification or add additional context in comments.

1 Comment

great alternative solution as well! I will test with both to see if performance is an issue and if so i will move the "false" items to a new list rather than do the copy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.