johajippijupp
johajippijupp

Reputation: 25

Checking if list element in list of lists and returning sublist

I have two lists

list1 = ['B', 'C', 'D']
list2 = [['1', 'A'], ['2', 'B'], ['3', 'D'], ['5', 'C']]

and want to return those sublistst of list2 that contain elements of list1. So far I tried using any:

result = []

for l2 in list2:
    if any (item in l2 for item in list1):
        result.append(l2)

and a naive approach

for l2 in list2:
    for l1 in l1:
        if l1 in l2:
            result.append(l2)

But I only managed to repeat empty list. The result should be

result = [['2', 'B'], ['5', 'C']]

Not sure, where I'm going wrong. Is there maybe a way using list comprehensions or mixing list comprehensions and 'any' function?

Upvotes: 0

Views: 62

Answers (3)

Martin
Martin

Reputation: 363

What you have looks correct and works for me locally too:

for l2 in list2:
    if any (item in l2 for item in list1):
        result.append(l2)

It returns [['2', 'B'], ['3', 'D'], ['5', 'C']] which is the expected result right?

Also note that you can speed up your implementation by changing list1 into a set list1 = set(['B', 'C', 'D']) and changing the if condition to if any (item in list1 for item in l2):.
This is because item in list1 is much faster if list1 is a set than a list. That's because set uses a hashmap under the hood the quickly accesss elements.

Upvotes: 1

alani
alani

Reputation: 13049

If the elements are hashable objects (as in this case with strings), then you can use set intersection:

>>> list1 = ['B', 'C', 'D']
>>> list2 = [['1', 'A'], ['2', 'B'], ['3', 'D'], ['5', 'C']]

>>> s = set(list1)
>>> [l for l in list2 if set(l) & s]
[['2', 'B'], ['3', 'D'], ['5', 'C']]

If the intersection is empty then this is treated as a false value for the purpose of the if filter in the list comprehension.

That said, I cannot reproduce the fact that your (first) code in the question is not working for you; it works fine when I try it. Your second code snippet (aside from the typo) has a potential problem of duplicated sublists in the output because you do not break from the inner loop after finding the first matching item.

Upvotes: 0

IoaTzimas
IoaTzimas

Reputation: 10624

Try this:

result=[i for i in list2 if any([k in i for k in list1])]
print(result)

[['2', 'B'], ['3', 'D'], ['5', 'C']]

Upvotes: 1

Related Questions