Encontrar elementos comunes a partir de dos listas de listas

Tengo dos listas de listas que contienen algunas coordenadas 3D como esta (por ejemplo):

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

¿Cuál será una forma rápida de encontrar si alguno de los elementos de “b” tiene alguna coordenada en la lista “a”? Por ejemplo, en el ejemplo dado, “a [2]” y “b [2] [1]” son iguales y quiero que el progtwig devuelva “true”.

Convierta las listas más internas de b en un conjunto ( s ), y luego itere sobre a para comprobar si existe algún elemento en a s o no.

 tot_items_b = sum(1 for x in b for y in x) #total items in b 

Los conjuntos proporcionan una búsqueda O(1) , por lo que la complejidad general será:

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) 

Manifestación:

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

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

Use set intersection para obtener todos los elementos comunes:

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

Use itertools.chain.from_iterable para aplanar la lista primero, luego simplemente itere a través de ella:

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

Utilizando 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 

prueba este código:

 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 

Funciona pero no estoy seguro de que sea rápido o no.