Reputation: 137
matched_edges = [(0, -1), (1, -1), (2, 3), (3, 2), (4, 6), (5, 7), (6, 4), (7, 5), (8, 9), (9, 8)]
process = matched_edges
print(process)
for tup in matched_edges:
if (tup[1], tup[0]) in process:
process.remove((tup[1], tup[0]))
if -1 in tup:
process.remove(tup)
print(tup)
print(process)
[(0, -1), (1, -1), (2, 3), (3, 2), (4, 6), (5, 7), (6, 4), (7, 5), (8, 9), (9, 8)]
(0, -1)
[(1, -1), (2, 3), (4, 6), (5, 7), (8, 9)]
I tried many ways, but I just can't remove (1,-1).What's wrong?
-1 in (1, -1)
True
Upvotes: 1
Views: 74
Reputation: 149
The following works fine for me.
matched_edges = [(0, -1), (1, -1), (2, 3), (3, 2), (4, 6),
(5, 7), (6, 4), (7, 5), (8, 9), (9, 8)]
process = []
for tup in matched_edges:
if (tup[0] != -1 and tup[1] != -1) and (tup[1], tup[0]) not in process:
process.append(tup)
print(process)
Output
[(2, 3), (4, 6), (5, 7), (8, 9)]
Upvotes: 0
Reputation: 590
The problem is that you do process = matched_edges
, you are creating a variable (process
) that points to the same object as matched_edges
, to create a new list with the same values you should do process = matched_edges[:]
instead.
So your code would look like:
matched_edges = [(0, -1), (1, -1), (2, 3), (3, 2), (4, 6), (5, 7), (6, 4), (7, 5), (8, 9), (9, 8)]
process = matched_edges[:]
print(process)
for tup in matched_edges:
if (tup[1], tup[0]) in process:
process.remove((tup[1], tup[0]))
if -1 in tup:
process.remove(tup)
print(tup)
print(process)
Upvotes: 0
Reputation: 417
This line process = matched_edges
is actually creating a reference to the matched_edges
list, not a copy of the items. In turn, this is affecting your iterator in the for loop as you remove items from process
(and matched_edges
). To demonstrate I slightly modified your code (just to print values):
matched_edges = [(0, -1), (1, -1), (2, 3), (3, 2), (4, 6), (5, 7), (6, 4), (7, 5), (8, 9), (9, 8)]
process = matched_edges
for tup in matched_edges:
print(f"Current tup: {tup}")
print(f"Process: {process}")
print(f"Matched: {matched_edges}")
if (tup[1], tup[0]) in process:
process.remove((tup[1], tup[0]))
if -1 in tup:
process.remove(tup)
Output:
Current tup: (0, -1)
Process: [(0, -1), (1, -1), (2, 3), (3, 2), (4, 6), (5, 7), (6, 4), (7, 5), (8, 9), (9, 8)]
Matched: [(0, -1), (1, -1), (2, 3), (3, 2), (4, 6), (5, 7), (6, 4), (7, 5), (8, 9), (9, 8)]
Current tup: (2, 3)
Process: [(1, -1), (2, 3), (3, 2), (4, 6), (5, 7), (6, 4), (7, 5), (8, 9), (9, 8)]
Matched: [(1, -1), (2, 3), (3, 2), (4, 6), (5, 7), (6, 4), (7, 5), (8, 9), (9, 8)]
Current tup: (4, 6)
Process: [(1, -1), (2, 3), (4, 6), (5, 7), (6, 4), (7, 5), (8, 9), (9, 8)]
Matched: [(1, -1), (2, 3), (4, 6), (5, 7), (6, 4), (7, 5), (8, 9), (9, 8)]
Current tup: (5, 7)
Process: [(1, -1), (2, 3), (4, 6), (5, 7), (7, 5), (8, 9), (9, 8)]
Matched: [(1, -1), (2, 3), (4, 6), (5, 7), (7, 5), (8, 9), (9, 8)]
Current tup: (8, 9)
Process: [(1, -1), (2, 3), (4, 6), (5, 7), (8, 9), (9, 8)]
Matched: [(1, -1), (2, 3), (4, 6), (5, 7), (8, 9), (9, 8)]
You can see on the second iteration you end up skipping the (1, -1)
tuple. In general, you're skipping an item every time you remove one.
Change your assignment to process
to use copy()
so you get a new list:
process = matched_edges.copy()
This should fix the odd behavior. Although I'm not quite sure if the loop you're using still does exactly what you intend it to, but this is the output with the copied list:
Current tup: (0, -1)
Process: [(0, -1), (1, -1), (2, 3), (3, 2), (4, 6), (5, 7), (6, 4), (7, 5), (8, 9), (9, 8)]
Matched: [(0, -1), (1, -1), (2, 3), (3, 2), (4, 6), (5, 7), (6, 4), (7, 5), (8, 9), (9, 8)]
Current tup: (1, -1)
Process: [(1, -1), (2, 3), (3, 2), (4, 6), (5, 7), (6, 4), (7, 5), (8, 9), (9, 8)]
Matched: [(0, -1), (1, -1), (2, 3), (3, 2), (4, 6), (5, 7), (6, 4), (7, 5), (8, 9), (9, 8)]
Current tup: (2, 3)
Process: [(2, 3), (3, 2), (4, 6), (5, 7), (6, 4), (7, 5), (8, 9), (9, 8)]
Matched: [(0, -1), (1, -1), (2, 3), (3, 2), (4, 6), (5, 7), (6, 4), (7, 5), (8, 9), (9, 8)]
Current tup: (3, 2)
Process: [(2, 3), (4, 6), (5, 7), (6, 4), (7, 5), (8, 9), (9, 8)]
Matched: [(0, -1), (1, -1), (2, 3), (3, 2), (4, 6), (5, 7), (6, 4), (7, 5), (8, 9), (9, 8)]
Current tup: (4, 6)
Process: [(4, 6), (5, 7), (6, 4), (7, 5), (8, 9), (9, 8)]
Matched: [(0, -1), (1, -1), (2, 3), (3, 2), (4, 6), (5, 7), (6, 4), (7, 5), (8, 9), (9, 8)]
Current tup: (5, 7)
Process: [(4, 6), (5, 7), (7, 5), (8, 9), (9, 8)]
Matched: [(0, -1), (1, -1), (2, 3), (3, 2), (4, 6), (5, 7), (6, 4), (7, 5), (8, 9), (9, 8)]
Current tup: (6, 4)
Process: [(4, 6), (5, 7), (8, 9), (9, 8)]
Matched: [(0, -1), (1, -1), (2, 3), (3, 2), (4, 6), (5, 7), (6, 4), (7, 5), (8, 9), (9, 8)]
Current tup: (7, 5)
Process: [(5, 7), (8, 9), (9, 8)]
Matched: [(0, -1), (1, -1), (2, 3), (3, 2), (4, 6), (5, 7), (6, 4), (7, 5), (8, 9), (9, 8)]
Current tup: (8, 9)
Process: [(8, 9), (9, 8)]
Matched: [(0, -1), (1, -1), (2, 3), (3, 2), (4, 6), (5, 7), (6, 4), (7, 5), (8, 9), (9, 8)]
Current tup: (9, 8)
Process: [(8, 9)]
Matched: [(0, -1), (1, -1), (2, 3), (3, 2), (4, 6), (5, 7), (6, 4), (7, 5), (8, 9), (9, 8)]
Upvotes: 1
Reputation: 98
Have you tried something like
process = [tup for tup in matched_edges if (tup[0] != -1 and tup[1] != -1)]
That should remove any tuple with -1 in it.
Edit
Also, the reason the code is behaving strangely is that matched_edges and process both hold the same object, so as you remove objects from process
you are also removing them from matched_edges
during iteration, resulting in unexpected bahaviour. Run the following code and you will see what I mean.
matched_edges = [(0, -1), (1, -1), (2, 3), (3, 2), (4, 6), (5, 7), (6, 4), (7, 5), (8, 9), (9, 8)]
process = matched_edges
print(process)
for tup in matched_edges:
print(tup)
print("Length of matched edges:", len(matched_edges))
if (tup[1], tup[0]) in process:
process.remove((tup[1], tup[0]))
if -1 in tup:
process.remove(tup)
print("removing", tup)
print(process)
matched_edges = [tup for tup in matched_edges if (tup[0] != -1 and tup[1] != -1)]
print(matched_edges)
Upvotes: 0
Reputation: 10719
This is the incorrect line
process = matched_edges
Here is a programming rule. As much as possible, do not update the object you are currently iterating on! What was done in your code is that process and matched_edges points/refers to the same object/list in heap memory (different stack variables but both pointing to the same memory address in heap which is the actual list) thus updating process means you are also indirectly updating matched_edges.
You are currently iterating matched_edges:
for tup in matched_edges:
Then, you updated process, which messed up your iteration of matched_edges:
process.remove(...)
The correction to your code is to use this instead:
process = matched_edges.copy()
Upvotes: 3
Reputation: 5889
You could just create a new list.
matched_edges = [(0, -1), (1, -1), (2, 3), (3, 2), (4, 6), (5, 7), (6, 4), (7, 5), (8, 9), (9, 8)]
process = []
for tup in matched_edges:
if (tup[1], tup[0]) in matched_edges:matched_edges.remove((tup[1], tup[0]))
if -1 not in tup:process.append(tup)
print(process)
output
[(2, 3), (4, 6), (5, 7), (8, 9)]
Upvotes: 0