簡體   English   中英

從兩個列表列表中查找公共元素

[英]Finding common elements from two lists of lists

我有兩個包含一些3D坐標的列表列表(例如):

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]]
b[n] = [[11, 22, 3], [42, 54, 36], [41, 2432, 34]]

如果“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(max(len(a), tot_items_b))

def func(a, b):
   #sets can't contain mutable items, so convert lists to tuple while storing

   s = set(tuple(y) for x in b for y in x)
   #s is set([(41, 2, 34), (98, 23, 56), (42, 25, 64),...])

   return any(tuple(item) in s for item in a)

演示:

>>> a = [[1, 2, 3], [4, 5, 6], [4, 2, 3]]
>>> 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]]]
>>> func(a,b)
True

any幫助:

>>> 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.

使用set intersection來獲取所有常見元素:

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

使用itertools.chain.from_iterable首先展平列表,然后簡單地遍歷它:

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

使用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, 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

它有效,但我不確定它是否快速。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM