0

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?

3
  • Where is ['3', 'D']? Commented Oct 2, 2020 at 11:22
  • 1
    Your first code snippet should give your expected output, and not empty list. Did you run your code? Commented Oct 2, 2020 at 11:23
  • And so does your second code snippet, as well - except for the typo: for l1 in list1: Commented Oct 2, 2020 at 11:25

3 Answers 3

1

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.

Sign up to request clarification or add additional context in comments.

Comments

1

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']]

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.