| | |
Removing elements from a list in a loop
![]() |
•
•
Join Date: Mar 2007
Posts: 9
Reputation:
Solved Threads: 0
Hi,
I'm having trouble removing objects from a list. It seems that when I remove single objects in a loop, the loop kind of skips elements in the list, not continuing from the point where the last removal occurred. I want to remove only certain elements from a list, and there should be a way for an object of the list to remove itself, or mark itself for removal.
Example code:
-Jusa
I'm having trouble removing objects from a list. It seems that when I remove single objects in a loop, the loop kind of skips elements in the list, not continuing from the point where the last removal occurred. I want to remove only certain elements from a list, and there should be a way for an object of the list to remove itself, or mark itself for removal.
Example code:
Python Syntax (Toggle Plain Text)
class FooObj: def __init__(self, i, a): self.i = i self.a = a def rem(self, list): #Doesn't work correctly list.remove(self) def __repr__(self): return "(obj " + str(self.i) + ", active = " + str(self.a) + ")" if __name__ == "__main__": o1 = FooObj(1, 1) o2 = FooObj(2, 0) o3 = FooObj(3, 0) o4 = FooObj(4, 1) o5 = FooObj(5, 1) #Test 1 lst = [o1, o2, o3, o4, o5] #Trying to remove objects flagged as inactive (a = 0) for obj in lst: if obj.a == 0: lst.remove(obj) #Prints: [(obj 1, active = 1), (obj 3, active = 0), (obj 4, active = 1), (obj 5, active = 1)] #^obj 3 is wrong! All objs with a=0 should be removed. print lst #Test 2 lst = [o1, o2, o3, o4, o5] #Trying to remove all objects. I need to be able to call a function of the object for each object in the loop. for obj in lst: obj.rem(lst) #Prints: [(obj 2, active = 0), (obj 4, active = 1)] #completely wrong print lst
-Jusa
•
•
Join Date: Sep 2005
Posts: 133
Reputation:
Solved Threads: 58
Hi,
your "error" is a very common source of confusion
Let's take a slightly simpler example:
Ok, let's go through the output step by step:
The first element in our list as an "a", it has the index 0 (the first index). It's not a "b" so we don't remove it and our list looks the same as before. Step 2:
Yeah, some action here! We are checking element number 2, with index 1, and it's a b -> remove it. Our list has now 3 elements ... alarm bells ringing? Let's look at Step 3:
See what happened? There is still a "b" here, but it is the second element, index 1. We already did something with the second element, in step 2. Now we are checking element number 3. It's a "d", so it stays and ... the loop is finished. Because we deleted one element, we jumped over one "b".
Thats what happens in your code.
What did we learn: Never delete something from or add something to the list you are iterating over.
The solution is: iterate over your original list, and put everything which passes your test into another list:
Regards, mawe
your "error" is a very common source of confusion

Let's take a slightly simpler example:
Python Syntax (Toggle Plain Text)
In [1]: lst = ["a", "b", "b", "d"] In [2]: for elem in lst: ....: print "before: ", lst # check the list ....: print elem, lst.index(elem) # check which element we are using ....: if elem == "b": # remove if element is a "b" ....: lst.remove(elem) ....: print "after: ", lst # check list again ....: print "-" * 20 ....: before: ['a', 'b', 'b', 'd'] a 0 after: ['a', 'b', 'b', 'd'] -------------------- before: ['a', 'b', 'b', 'd'] b 1 after: ['a', 'b', 'd'] -------------------- before: ['a', 'b', 'd'] d 2 after: ['a', 'b', 'd'] --------------------
Python Syntax (Toggle Plain Text)
before: ['a', 'b', 'b', 'd'] a 0 after: ['a', 'b', 'b', 'd']
Python Syntax (Toggle Plain Text)
before: ['a', 'b', 'b', 'd'] b 1 after: ['a', 'b', 'd']
Python Syntax (Toggle Plain Text)
before: ['a', 'b', 'd'] d 2 after: ['a', 'b', 'd']
Thats what happens in your code.
What did we learn: Never delete something from or add something to the list you are iterating over.
The solution is: iterate over your original list, and put everything which passes your test into another list:
Python Syntax (Toggle Plain Text)
lst2 = [ elem for elem in lst if elem != "b" ]
Regards, mawe
•
•
Join Date: Jul 2006
Posts: 608
Reputation:
Solved Threads: 150
Good one, mawe.
If you need to filter the list in a more complicated way, you can also do this:
so we iterate through a *copy* of mylist, but remove items from the original.
Jeff
If you need to filter the list in a more complicated way, you can also do this:
Python Syntax (Toggle Plain Text)
for item in mylist[:]: if item_is_a_reject(): #whatever test you need to run goes here mylist.remove(item)
so we iterate through a *copy* of mylist, but remove items from the original.
Jeff
•
•
Join Date: Sep 2005
Posts: 133
Reputation:
Solved Threads: 58
You are right, that's another way. It may be a matter of taste, but ... I don't like it
I would rather do something like this:
and then as above
or, because I'm a big fan of functional programming
But as I said, it's just a matter of taste
I would rather do something like this: Python Syntax (Toggle Plain Text)
In [1]: def valid( elem ): # very complicated function ...: if elem < 0: return False ...: return True
Python Syntax (Toggle Plain Text)
In [2]: lst = [-3, 2, -5, -10, 12] In [3]: [ elem for elem in lst if valid(elem) ] Out[3]: [2, 12]
Python Syntax (Toggle Plain Text)
In [4]: filter(valid, lst) Out[4]: [2, 12]
•
•
Join Date: Oct 2007
Posts: 1
Reputation:
Solved Threads: 0
1. Implement the linked list program with the Vectors concepts that you have learnt.
2. Take 1 Vector and store all the values in it.
3. Take another vector and store the addresses of the next value (in this context it would be the indexes of the first vector).
4. So far Example, If you want to insert an element at the end, insert it to the end of the first vector and store its index in the second vector.
5. Similarly, If you want to insert an element in the beginning of the list:
1. Insert the value at the end of the first array.
2. Now, Shuffle all the addresses in the second Vector appropriately.
6. Please click here for the example document.
I want coding for these 6 ?
2. Take 1 Vector and store all the values in it.
3. Take another vector and store the addresses of the next value (in this context it would be the indexes of the first vector).
4. So far Example, If you want to insert an element at the end, insert it to the end of the first vector and store its index in the second vector.
5. Similarly, If you want to insert an element in the beginning of the list:
1. Insert the value at the end of the first array.
2. Now, Shuffle all the addresses in the second Vector appropriately.
6. Please click here for the example document.
I want coding for these 6 ?
![]() |
Similar Threads
- [req]How to move elements in the list box up and down using command button? (Visual Basic 4 / 5 / 6)
- remove method linked list (C)
- MySQL query to loop through results distinctly (MySQL)
- reading input ... quick C++ question ... (C++)
Other Threads in the Python Forum
- Previous Thread: need help please
- Next Thread: Graphics help...
| Thread Tools | Search this Thread |
alarm assignment avogadro beginner bluetooth character cmd code customdialog cx-freeze data decimals dictionary directory dynamic error examples exe file float format function generator getvalue gnu graphics gui halp homework http ideas import input ip itunes java leftmouse line linux list lists logging loop maintain maze millimeter module mouse number numbers output parsing path port prime programming projects push py2exe pygame pyglet pyqt python queue random recursion schedule screensaverloopinactive script scrolledtext slicenotation sqlite ssh stdout string strings sudokusolver table terminal text thread threading time tlapse tuple tutorial ubuntu unicode urllib urllib2 variable variables ventrilo verify vigenere web webservice wikipedia wxpython xlib





