Remove items from one list based on the contents of another

Viewed 102

I am trying to remove all entities in one list from another.

One of the lists is a list of lists.

Whilst another is a list of tuples.

ScoutNameList = [[('Rory', 'Adair')], [('Fiona', 'Adair')]]
ScoutNamedFromPatrol = [('Rory', 'Adair'), ('Fiona', 'Adair'), ('Ruariri', 'OBrien')]
ScoutNamedFromPatrol.remove(ScoutNameList)

Expected Result

ScoutNamedFromPatrol=[('Ruariri', 'OBrien')]

Actual Result

ScoutNamed=[('Rory', 'Adair'), ('Fiona', 'Adair'), ('Ruariri', 'OBrien')]
5 Answers
>>> for l in ScoutNameList:
    ScoutNamedFromPatrol.remove(l[0])
>>> ScoutNamedFromPatrol
[('Ruariri', 'OBrien')]

You can use list comprehensions -

ScoutNamedFromPatrol = [s for s in ScoutNamedFromPatrol if [s] not in ScoutNameList]

You can use a list comprehension. However, note that you have to flatten ScoutNameList, you can do that with itertools.chain:

[i for i in ScoutNamedFromPatrol if i not in chain(*ScoutNameList)]
#[('Ruariri', 'OBrien')]

Where:

list(chain(*ScoutNameList))
#[('Rory', 'Adair'), ('Fiona', 'Adair')]

If order is not important, you can use set.difference or its syntactic sugar -. Since ScoutNameList is nested, with each sublist containing a single item, you can use operator.itemgetter with map to construct an iterable of scalars.

from operator import itemgetter

res = list(set(ScoutNamedFromPatrol) - set(map(itemgetter(0), ScoutNameList)))
# [('Ruariri', 'OBrien')]

A less functional alternative suggested by @TrebuchetMS:

res = list(set(ScoutNamedFromPatrol) - set(x[0] for x in ScoutNameList))

A more adaptable version can deal with multiple items in inner lists of ScoutNameList:

from itertools import chain
res = list(set(ScoutNamedFromPatrol) - set(chain.from_iterable(ScoutNameList)))

try this

ScoutNameList = [[('Rory', 'Adair')], [('Fiona', 'Adair')]]
ScoutNamedFromPatrol = [('Rory', 'Adair'), ('Fiona', 'Adair'), ('Ruariri', 'OBrien')]
for x in ScoutNameList:
    for y in x:
        if y in ScoutNamedFromPatrol:

            ScoutNamedFromPatrol.remove(y)

print(ScoutNamedFromPatrol)
Related