[英]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.并且想要返回那些包含 list1 元素的 list2 的 sublistst。 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?
有没有办法使用列表理解或混合列表理解和“任何”函数?
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']]
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?它返回
[['2', 'B'], ['3', 'D'], ['5', 'C']]
这是预期的结果,对吗?
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):
.另请注意,您可以通过将 list1 更改为 set
list1 = set(['B', 'C', 'D'])
并将 if 条件更改为if any (item in list1 for item in l2):
来加快实现速度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
.这是因为如果
list1
是一个set
不是一个list
那么list1
中的item in list1
会快得多。 That's because set
uses a hashmap under the hood the quickly accesss elements.那是因为
set
在后台使用了一个 hashmap 来快速访问元素。
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.如果交集为空,则出于列表理解中的
if
过滤器的目的,将其视为假值。
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.您的第二个代码片段(除了拼写错误)在输出中存在重复子列表的潜在问题,因为您在找到第一个匹配项后没有
break
内部循环。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.