1

I've done my reading trust me. And python still acts up when removing an item from the list. I have a graph implementation.

Now there is this one function that is supposed to delete some edges that the node has attached. I have a list of Edge objects and want to remove them by value...

Code is something like this:

for edge in node.edgeList: ... edgeToRemove = edge # edgeToRemove now holds something like <edge.Edge object at 0x107dcaf90> node.edgeList.remove(edgeToRemove) #KINDA WORKS - just doesnt behave consistently...It removes some edges but not others 

What is the best way to remove them?

3 Answers 3

6

Don't change the length of a list while iterating over it. It won't work.

>>> l = range(10) >>> for i in l: ... l.remove(i) ... >>> l [1, 3, 5, 7, 9] 

See? The problem is that when you remove an item, the following items are all shifted back by one, but the location of the index remains the same. The effect is that the item after the removed item gets skipped. Depending on what you're doing, a list comprehension is preferable.

>>> l = range(10) >>> for i in l: ... if i in [2, 3, 5, 6, 8, 9]: ... l.remove(i) ... >>> l [0, 1, 3, 4, 6, 7, 9] >>> [i for i in range(10) if not i in [2, 3, 5, 6, 8, 9]] [0, 1, 4, 7] 
Sign up to request clarification or add additional context in comments.

5 Comments

Another approach is to iterate over the list in reverse order using reversed(). That way, deleting an item only shifts the items you've already seen.
@user965847, yes.
thanks :) I will figure out a solution myself no problem I just didnt realize you shouldnt do this...
or you iterate over a copy of the list, and only remove from the parent list. for i in l[:]:
@kindall, @GoingTharn, both good points. In general, though, I prefer a list comprehension most of the time (with slice-assignment for in-place operations, i.e. x[:] = [i for i in x if foo]), because every time you call x.remove(v), x.pop(i), or del x[i], all the following items in the list must be shifted by one. So when you iterate over a list, removing many items, you're using the Shlemiel the painter's algorithm. :)
1

Get the index of the element and del it.

del somelist[n] 

Comments

0

You could use lit comprehension - although your problem may be in your __eq__/__ne__ methods for edges (you should post that). Try this, though:

node.edgeList = [edge for edge in node.edgeList if edge != edgeToRemove] 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.