2012-04-08 27 views
16

Estoy tratando de encontrar la manera de comparar una n cantidad de listas para encontrar los elementos comunes. Por ejemplo:¿Cómo encontrar elementos comunes en la lista de listas?

p=[ [1,2,3], 
    [1,9,9], 
     .. 
     .. 
    [1,2,4] 

>> print common(p) 
>> [1] 

Ahora si sé el número de elementos que pueda hacer comparions como:

for a in b: 
    for c in d: 
    for x in y: 
... 

pero eso no funcionará si no sé cuántos elementos tiene p. He visto esta solución que compara dos listas https://stackoverflow.com/a/1388864/1320800

pero después de haber pasado 4 horas tratando de encontrar la forma de hacer eso recursivo, todavía se me escapa una solución por lo que cualquier ayuda sería muy apreciada.

+0

posible duplicado de [Python: ¿Cómo encontrar intersección de lista?] (Http://stackoverflow.com/questions/3697432/python-how-to-find-list-intersection) –

+0

¿su solución tiene que ser recursiva? ¿Puedes usar las funciones integradas 'intersect' (es decir, ¿es tarea?)? –

+0

No sabía que el término correcto era "intersección", así que gracias por eso. Me ayudará a investigarlo más.Ahora, no tiene que ser recursivo, pero acabamos de enterarnos de la recursividad, así que pensé que probablemente tendría que comparar p [0] yp [1] y luego alimentar el resultado con el resto de los elementos, es por eso que pensó que probablemente sería una solución recursiva – 8bits

Respuesta

33

Usted está buscando la intersección de conjuntos de todos los sub-listas, y el tipo de datos que debes usar para operaciones de conjuntos es un conjunto:

result = set(p[0]) 
for s in p[1:]: 
    result.intersection_update(s) 
print result 
+2

+1 para usar conjuntos donde los conjuntos son del tipo de datos apropiado. –

+0

Gracias por la respuesta .. No sabía nada acerca de los conjuntos, así que voy a investigar un poco más. Sin embargo, a partir de una prueba preliminar p = [[1,2,3], [1,3], [8,1]] la solución que usted propuso en lugar de [1] devuelve [8,1]? – 8bits

+0

@ user1320800: La primera versión de esta respuesta tenía una declaración 'print' incorrecta al final. Por supuesto, debemos imprimir 'resultado', no' s'. –

1
reduce(lambda x, y: x & y, (set(i) for i in p)) 
+1

'reduce' no se considera" Pythonic "por muchos. Además, su versión requiere que cada lista se convierta en un conjunto, y un nuevo conjunto adicional para ser creado para cada intersección. La versión de Sven crea solo un conjunto. – agf

+0

@agf: Entendido. Aún así, es una solución de trabajo (aunque ligeramente ineficaz). –

1
p=[ [1,2,3], 
    [1,9,9], 
    [1,2,4]] 

ans = [ele[0] for ele in zip(*p) if len(set(ele)) == 1] 

Resultado:

>>> ans 
[1] 
+1

Pruebe esto con p = [[1,2], [2,1 ]]. O incluso p = [[1,2], [2]]. – DSM

+0

Mi código solo funciona, si miramos todos los elementos comunes que también están en la misma posición, esa es la esencia del zip (* p). Eso es lo que pensé que OP quería, pero leyendo la publicación de nuevo, probablemente no entendí. También asumí que cada sublista tiene la misma longitud. – Akavall

+0

Además, 'zip' soltará elementos si las listas varían en longitud. –

4

¿Por qué no solo:

set.intersection(*map(set, p)) 

Resultado:

set([1]) 

O así:

ip = iter(p) 
s = set(next(ip)) 
s.intersection(*ip) 

Resultado:

set([1]) 

edición:

copiado de consola:

>>> p = [[1,2,3], [1,9,9], [1,2,4]] 
>>> set.intersection(*map(set, p)) 
set([1]) 
>>> ip = iter(p) 
>>> s = set(next(ip)) 
>>> s.intersection(*ip) 
set([1]) 
+0

No sé si me falta algo, pero pasar p = [[1,2,3], [1,9,9], [1,2,4]] no pareció funcionar – 8bits

+0

@ 8bits: Por favor, mira mi edición. – pillmuncher

10
>>> p=[ [1,2,3], 
    [1,9,9], 
    [1,2,4]] 
>>> set(p[0]).intersection(*p) 
set([1]) 
1

Una solución simple (una línea) es:

set.intersection(*[set(list) for list in p]) 
0

Usted está buscando la intersección de conjuntos de todos los sub-listas, y el tipo de datos que debes usar para operaciones de conjuntos es un conjunto:

result = set(p[0]) 
for s in p[1:]: 
    result.intersection_update(s) 
print result 

Sin embargo, hay una limitación de 10 listas en una lista. Cualquier cosa más grande hace que la lista de 'resultados' esté fuera de servicio. Asumiendo que ha hecho 'resultado' en una lista por list(result).

Asegúrate de result.sort() para asegurarte de que esté ordenado si dependes de esa forma.

Cuestiones relacionadas