Python 从两个列表中查找公共元素

Python 从两个列表中查找公共元素,python,list,Python,List,我有两个列表,其中包含一些像这样的3D坐标(例如): 如果“b”的任何元素在列表“a”中有坐标,那么什么是快速查找的方法?例如,在给定的示例中,“a[2]”和“b[2][1]”是相同的,因此我希望程序返回“true” 将b的最内层列表转换为一个集合(s),然后迭代a,检查a中的任何项目是否存在于s中 tot_items_b = sum(1 for x in b for y in x) #total items in b 集合提供了一个O(1)查找,因此总体复杂性将是: O(最大值(长度(a)、

我有两个列表,其中包含一些像这样的3D坐标(例如):


如果“b”的任何元素在列表“a”中有坐标,那么什么是快速查找的方法?例如,在给定的示例中,“a[2]”和“b[2][1]”是相同的,因此我希望程序返回“true”

b
的最内层列表转换为一个集合(
s
),然后迭代
a
,检查
a
中的任何项目是否存在于
s

tot_items_b = sum(1 for x in b for y in x) #total items in b
集合提供了一个
O(1)
查找,因此总体复杂性将是:

O(最大值(长度(a)、总计项目(b))

演示:

有关
任何
的帮助:

>>> print any.__doc__
any(iterable) -> bool

Return True if bool(x) is True for any x in the iterable.
If the iterable is empty, return False.
使用“设置交点”获取所有公共图元:

>>> s_b = set(tuple(y) for x in b for y in x)
>>> s_a = set(tuple(x) for x in a)
>>> s_a & s_b
set([(4, 5, 6)])
用于首先展平列表,然后简单地遍历它:

>>> B = [[[11, 22, 3], [12, 34, 6], [41, 2, 34], [198, 213, 536], [1198, 1123, 1156]], [[11, 22, 3], [42, 25, 64], [43, 45, 23]], [[3, 532, 23], [4, 5, 6], [98, 23, 56], [918, 231, 526]], [[11, 22, 3], [42, 54, 36], [41, 2432, 34]]]
>>> A = [[1, 2, 3], [4, 5, 6], [4, 2, 3]]
>>> for i in itertools.chain.from_iterable(B):
...     if i in A:
...             print True, i
... 
True [4, 5, 6]
请尝试以下代码:

a = [[1, 2, 3], [4, 5, 6], [4, 2, 3]]
b={}
b[0] = [[11, 22, 3], [12, 34, 6], [41, 2, 34], [198, 213, 536], [1198, 1123, 1156]]
b[1] = [[11, 22, 3], [42, 25, 64], [43, 45, 23]]
b[2] = [[3, 532, 23], [4, 5, 6], [98, 23, 56], [918, 231, 526]]
b[3] = [[11, 22, 3], [42, 54, 36], [41, 2432, 34]]

for i in b:
    for ii in i:
        if ii in a:
            return True
它可以工作,但我不确定它是否快。

使用numpy:

import numpy
b=[ [], [] , [] ]
a = [[1, 2, 3], [4, 5, 6], [4, 2, 3]]
b[0] = [[11, 22, 3], [12, 34, 6], [41, 2, 34], [198, 213, 536], 
        [1198, 1123, 1156]]
b[1] = [[11, 22, 3], [42, 25, 64], [43, 45, 23]]
b[2] = [[3, 532, 23], [4, 5, 6], [98, 23, 56], [918, 231, 526]]

for p1 in a:
    for p2 in [ p for bb in b for p in bb]:
        v=numpy.linalg.norm(numpy.array(p1)-numpy.array(p2))
        if v == 0: print p1

你的问题是指
a[1]
b[2][1]
?是的,对不起!我将编辑它。是否可以编辑此程序以输出公共元素?谢谢大家!@jhaprade第一个公共元素还是所有元素?我相信复杂性是
O(max(len(a),sum{I=0}^{len(b)-1}{len(b[I]))}
,因为在创建
集时,你正在做一个嵌套循环。@Ashwini如果可能的话,我想拥有所有元素。@Bakuriu哇!说得好。但是我不明白你在用什么符号?@Jared Fast是一种扁平化列表的方法。使用
any
和生成器-
any(a中的ii表示I中的b表示I中的ii)
,它会更快,但它可能仍然无法与使用集合的答案竞争(可能只有非常小的输入大小除外)。它可能会与
itertools.chain
解决方案竞争,但可能仍然会慢一点。@lvc competite?嘿,这不是比赛。我只是提供我的答案,因为这是回答这个问题的另一种方式。你应该将
b
初始化为一个列表:
b=[]
,而不是dict。否则,在I:
中的ii的循环中,你实际上是在尝试迭代一个整数。
>>> B = [[[11, 22, 3], [12, 34, 6], [41, 2, 34], [198, 213, 536], [1198, 1123, 1156]], [[11, 22, 3], [42, 25, 64], [43, 45, 23]], [[3, 532, 23], [4, 5, 6], [98, 23, 56], [918, 231, 526]], [[11, 22, 3], [42, 54, 36], [41, 2432, 34]]]
>>> A = [[1, 2, 3], [4, 5, 6], [4, 2, 3]]
>>> for i in itertools.chain.from_iterable(B):
...     if i in A:
...             print True, i
... 
True [4, 5, 6]
a = [[1, 2, 3], [4, 5, 6], [4, 2, 3]]
b={}
b[0] = [[11, 22, 3], [12, 34, 6], [41, 2, 34], [198, 213, 536], [1198, 1123, 1156]]
b[1] = [[11, 22, 3], [42, 25, 64], [43, 45, 23]]
b[2] = [[3, 532, 23], [4, 5, 6], [98, 23, 56], [918, 231, 526]]
b[3] = [[11, 22, 3], [42, 54, 36], [41, 2432, 34]]

for i in b:
    for ii in i:
        if ii in a:
            return True
import numpy
b=[ [], [] , [] ]
a = [[1, 2, 3], [4, 5, 6], [4, 2, 3]]
b[0] = [[11, 22, 3], [12, 34, 6], [41, 2, 34], [198, 213, 536], 
        [1198, 1123, 1156]]
b[1] = [[11, 22, 3], [42, 25, 64], [43, 45, 23]]
b[2] = [[3, 532, 23], [4, 5, 6], [98, 23, 56], [918, 231, 526]]

for p1 in a:
    for p2 in [ p for bb in b for p in bb]:
        v=numpy.linalg.norm(numpy.array(p1)-numpy.array(p2))
        if v == 0: print p1