Issue 15214: Warn against removing elements from a list (or seq) while iterating (original) (raw)
The simple repro below, shows that if a list of strings has two consecutive items that begin with the same letter, an iteration over the list to find and remove all strings that start with that letter fails. The second string that starts with the same letter to remove remains in the list.
In the example below, both "bananna" and "blueberry" should be removed from the list, but only "bananna" is removed.
I verified this on both 2.7 and 3.2.
--- Output ---
Before: ['apple', 'bananna', 'blueberry', 'coconut'] After: ['apple', 'blueberry', 'coconut']
--- Repro ---
itemList = ["apple", "bananna", "blueberry", "coconut"] print("Before: {0}".format(itemList))
for item in itemList: if(item.startswith("b")): itemList.remove(item)
print("After: {0}".format(itemList))
This happens because you modify the list while iterating over it, which makes the loop not work as you expect. Essentially, when you remove the item that's currently being pointed to, the loop skips over the next item.
An idiomatic way to remove items from a list is to use a list comprehension to create a new list without the unwanted items:
item_list = ["apple", "bananna", "blueberry", "coconut"] new_list = [item for item in item_list if not item.startswith('b')]