如何检查一个列表中的任何元组是否在另一个列表中?

时间:2018-03-08 19:37:34

标签: python list set tuples set-union

我遇到的麻烦是这些元组位于列表列表中,如下所示:

giantlist = [[[(0,2), (2,3), (4,5)],[(0,2), (3,4), (6,8)], [(3,4),(0,2)]]]

所以,我的问题是试图遍历每个列表并找出它们是否有共同的元组,然后我想打印“找到列表1和列表2之间的公共点”。

例如: 列表列表中的第一个列表是

[(0,2),(2,3),(4,5)]

它有一个共同的元组,第二个列表是点[(0,2)]

下面显示的第三个列表也有公共点[(0,2)]

[(3,4),(0,2)]

我想打印list1与list2和list3

有共同点

我尝试了很多不同的循环,但是我在比较列表方面遇到了麻烦,因为我无法正确地对它们进行索引。我想我可以找到这些列表之间的交集,如果它们有交叉点,那么我会打印。

我还发现,也许我可以得到每个列表的长度然后将它们联合起来并检查联合长度是否小于两个列表的长度,这意味着它们有一个共同的元组。

2 个答案:

答案 0 :(得分:3)

查看两个列表是否有任何交集的最简单方法是将它们转换为集合,然后使用intersection方法或&运算符:

>>> lst1 = [(0,2),(2,3),(4,5)]
>>> lst2 = [(3,4),(0,2)]
>>> set(lst1) & set(lst2)
{(0, 2)}

如果效率(空间或速度)是一个问题,您可能只想将较小的一个转换为一组:

>>> set(lst1).intersection(lst2) if len(lst1) > len(lst2) else set(lst2).intersection(lst1)

但实际上,这就像你可能需要的那样复杂。

当然,这并不能解决你的整个任务,只是你所坚持的部分。你仍然需要弄清楚如何将它应用于每对列表(或者你可以做的比将它应用于每对列表更有效)。

答案 1 :(得分:1)

现有工具。例如,您可以使用collections.Counter作为O(n)解决方案,并将其与@hexparrot's flattener function结合使用:

from collections import Counter

giantlist = [[[(0,2), (2,3), (4,5)],[(0,2), (3,4), (6,8)], [(3,4),(0,2)]]]

def flatten(container):
    for i in container:
        if isinstance(i, list):
            for j in flatten(i):
                yield j
        else:
            yield i

c = Counter(flatten(giantlist))

Result是一个将每个元组映射到其计数的字典:

Counter({(0, 2): 3, (3, 4): 2, (2, 3): 1, (4, 5): 1, (6, 8): 1})

您可以调整上述解决方案,以便在特定列表之间进行比较,可能通过itertools.combinations