1
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

Nice Chang
  • 67
  • 1
  • 7
  • What condition must be met for the tuple to be removed? – Buddy Bob Apr 28 '21 at 03:18
  • When -1 in the tuple or the same but different order tuples.Like (1,2) and (2,1), then I need to remove one of it. – Nice Chang Apr 28 '21 at 03:19
  • Does this answer your question? [Is there a simple way to delete a list element by value?](https://stackoverflow.com/questions/2793324/is-there-a-simple-way-to-delete-a-list-element-by-value) – Nicholas Hunter Apr 28 '21 at 03:24
  • bear in mind that `process` and `matched_edges` are references to the same list, so you are [iterating](https://stackoverflow.com/questions/1207406/how-to-remove-items-from-a-list-while-iterating) over a list whilst removing from it. – Paul Rooney Apr 28 '21 at 03:25
  • Given your explanation @NiceChang `when -1 in tuple or reversed tuple exists` it seems your entire list would be removed? – PacketLoss Apr 28 '21 at 03:27

6 Answers6

3

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()
1

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)]
Aelarion
  • 397
  • 4
  • 11
0

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)
0

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)]
Buddy Bob
  • 5,829
  • 1
  • 13
  • 44
0

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)
Giovanni Rescia
  • 605
  • 5
  • 15
0

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)]
Vignesh G
  • 151
  • 6