Home > Mobile >  Remove tuples from a list
Remove tuples from a list

Time:10-24

I have the two lists below:

list1 = [(1, 'A'), (2, 'B'), (3, '?'), (4, 'T'), (5, 'A'), (6, 'B'), (7, '?'), (8, 'T')]
list2 = [(2, 'D'), (6, 'E'), (7, '!'), (10, 'T')]

I need to remove from list1 the elements in common with list2 that are in first position. So, I've used the for loop below:

for x in list1:
    id_list1 = x[0]

    for y in list2:
        id_list2 = y[0]

        if id_list1 == id_list2:
            list1.remove(x)

The output is: [(1, 'A'), (3, '?'), (4, 'T'), (5, 'A'), (7, '?'), (8, 'T')]

The result is strange because I see (7, '?') in list1 but not (2, 'B') and (6, 'B'). The last two tuples are correctly removed, but why not (7, '?')?

The expected output is: [(1, 'A'), (3, '?'), (4, 'T'), (5, 'A'), (8, 'T')]

CodePudding user response:

You can use:

list1 = [(1, "A"), (2, "B"), (3, "?"), (4, "T"), (5, "A"), (6, "B"), (7, "?"), (8, "T")]
list2 = [(2, "D"), (6, "E"), (7, "!"), (10, "T")]

first_items = set(i for i, _ in list2)
list1[:] = [item for item in list1 if item[0] not in first_items]
print(list1)

output:

[(1, 'A'), (3, '?'), (4, 'T'), (5, 'A'), (8, 'T')]

Basically you create a set from first items of the list2, then with a list comprehension you pick items from list1 whose first items are not appear in that list. list1[:] does the job in-place.

Set is chosen because of O(1) membership testing. You could use list or tuple if you're dealing with small lists.

But why your own solution doesn't work:
You shouldn't remove something from a list while you're iterating over it:

To fix it, change for x in list1 to for x in list1[:]. Now you're iterating over a copy of that list.

CodePudding user response:

Try:

list1 = [(1, 'A'), (2, 'B'), (3, '?'), (4, 'T'), (5, 'A'), (6, 'B'), (7, '?'), (8, 'T')]
list2 = [(2, 'D'), (6, 'E'), (7, '!'), (10, 'T')]
for x in list1[:]:
    id_list1 = x[0]

    for y in list2:
        id_list2 = y[0]

        if id_list1 == id_list2:
            list1.remove(x)
print(list1)

the reason for the weird behaviour is because when u remove an element from list1, elemensts shift to the left so i might skip an ele.

  • Related