Sé cómo obtener una intersección de dos listas planas:
b1 = [1,2,3,4,5,9,11,15]
b2 = [4,5,6,7,8]
b3 = [val for val in b1 if val in b2]
o
def intersect(a, b):
return list(set(a) & set(b))
print intersect(b1, b2)
Pero cuando tengo que encontrar la intersección de las listas anidadas, comienzan mis problemas:
c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]
c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]
Al final me gustaría recibir:
c3 = [[13,32],[7,13,28],[1,6]]
¿Pueden echarme una mano con esto?
Relacionado
python
list
intersection
elfuego1
fuente
fuente
Respuestas:
Si tu quieres:
Entonces aquí está su solución para Python 2:
En Python 3
filter
devuelve un iterable en lugar delist
, por lo que debe ajustar lasfilter
llamadas conlist()
:Explicación:
La parte del filtro toma cada elemento de la sublista y verifica si está en la lista de origen c1. La comprensión de la lista se ejecuta para cada sublista en c2.
fuente
filter(set(c1).__contains__, sublist)
para la eficiencia. Por cierto, la ventaja de esta solución es quefilter()
conserva los tipos de cadenas y tuplas.c3 = [[x for x in sublist if x in c1] for sublist in c2]
No necesita definir la intersección. Ya es una parte de primera clase del set.
fuente
set(b1) & set(b2)
? OMI es más limpio para usar el operador.set
conducirá a un código que es de órdenes de magnitud más rápido. Aquí hay una muestra de benchmark®: gist.github.com/andersonvom/4d7e551b4c0418de3160Para las personas que solo buscan encontrar la intersección de dos listas, el Asker proporcionó dos métodos:
Pero hay un método híbrido que es más eficiente, porque solo tiene que hacer una conversión entre lista / conjunto, en lugar de tres:
Esto se ejecutará en O (n), mientras que su método original de comprensión de listas se ejecutará en O (n ^ 2)
fuente
El enfoque funcional:
y se puede aplicar al caso más general de las listas 1+
fuente
set(*input_list[:1]).intersection(*input_list[1:])
. Versión iterador (it = iter(input_list)
):reduce(set.intersection, it, set(next(it, [])))
. Ambas versiones no requieren convertir todas las listas de entrada para establecer. Este último es más eficiente en memoria.from functools import reduce
para usarlo en Python 3. O mejor aún, use unfor
bucle explícito .Versión de comprensión de lista pura
Aplanar variante:
Variante anidada:
fuente
El operador & toma la intersección de dos conjuntos.
fuente
Una forma pitónica de tomar la intersección de 2 listas es:
fuente
Debería aplanar usando este código (tomado de http://kogs-www.informatik.uni-hamburg.de/~meine/python_tricks ), el código no ha sido probado, pero estoy bastante seguro de que funciona:
Después de aplanar la lista, realiza la intersección de la manera habitual:
fuente
Desde que
intersect
se definió, una comprensión básica de la lista es suficiente:Mejora gracias a la observación de S. Lott y la observación asociada de TM .:
fuente
Dado:
Creo que el siguiente código funciona bien y tal vez sea más conciso si se usa la operación set:
Llegó:
Si se necesita orden:
tenemos:
Por cierto, para un estilo más python, este también está bien:
fuente
No sé si llego tarde a responder tu pregunta. Después de leer su pregunta, se me ocurrió una función intersect () que puede funcionar tanto en la lista como en la lista anidada. Utilicé la recursión para definir esta función, es muy intuitiva. Espero que sea lo que estás buscando:
Ejemplo:
fuente
¿Consideras
[1,2]
cruzarte con[1, [2]]
? Es decir, ¿solo le importan los números o la estructura de la lista?Si solo son los números, investigue cómo "aplanar" las listas, luego use el
set()
método.fuente
También estaba buscando una manera de hacerlo, y finalmente terminó así:
fuente
fuente
Podemos usar métodos establecidos para esto:
fuente
Para definir la intersección que tenga en cuenta correctamente la cardinalidad de los elementos, utilice
Counter
:fuente
Aquí hay una forma de establecer
c3
que no involucra conjuntos:Pero si prefiere usar solo una línea, puede hacer esto:
Es una comprensión de lista dentro de una comprensión de lista, lo cual es un poco inusual, pero creo que no deberías tener demasiados problemas para seguirla.
fuente
Para mí, esta es una forma muy elegante y rápida de hacerlo :)
fuente
La lista plana se puede hacer
reduce
fácilmente.Todo lo que necesitas para usar initializer - tercer argumento en la
reduce
función.El código anterior funciona tanto para python2 como para python3, pero debe importar el módulo de reducción como
from functools import reduce
. Consulte el siguiente enlace para más detalles.para python2
para python3
fuente
Manera simple de encontrar la diferencia y la intersección entre iterables
Use este método si la repetición es importante
fuente