¿Cómo encontrar elementos que son comunes a todas las listas en una lista anidada?

Tengo una lista anidada grande y cada lista dentro de la lista anidada contiene una lista de números que están formateados como flotadores. Sin embargo, cada lista individual en la lista anidada es la misma, excepto por algunas excepciones. Quiero extraer los números que son comunes a todas las listas en la lista anidada. Un ejemplo simple de mi problema se muestra a continuación:

nested_list = [[1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0], [2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0], [1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0], [2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0]] 

En el siguiente caso me gustaría extraer lo siguiente:

 common_vals = [2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0] 

Intenté usar conjuntos de intersecciones para resolver esto, pero como no pude hacer que esto funcionara en todos los elementos de la lista anidada.

Puedes usar reduce y set.intersection :

 >>> reduce(set.intersection, map(set, nested_list)) set([2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0]) 

Utilice itertools.imap para una solución eficiente de la memoria.

Comparaciones de tiempo:

 >>> lis = [[1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0], [2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0], [1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0], [2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0]] >>> %timeit set.intersection(*map(set, lis)) 100000 loops, best of 3: 12.5 us per loop >>> %timeit set.intersection(*(set(e) for e in lis)) 10000 loops, best of 3: 14.4 us per loop >>> %timeit reduce(set.intersection, map(set, lis)) 10000 loops, best of 3: 12.8 us per loop >>> %timeit reduce(set.intersection, imap(set, lis)) 100000 loops, best of 3: 13.1 us per loop >>> %timeit set.intersection(set(lis[0]), *islice(lis, 1, None)) 100000 loops, best of 3: 10.6 us per loop >>> lis = [[1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0], [2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0], [1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0], [2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0]]*1000 >>> %timeit set.intersection(*map(set, lis)) 10 loops, best of 3: 16.4 ms per loop >>> %timeit set.intersection(*(set(e) for e in lis)) 10 loops, best of 3: 15.8 ms per loop >>> %timeit reduce(set.intersection, map(set, lis)) 100 loops, best of 3: 16.3 ms per loop >>> %timeit reduce(set.intersection, imap(set, lis)) 10 loops, best of 3: 13.8 ms per loop >>> %timeit set.intersection(set(lis[0]), *islice(lis, 1, None)) 100 loops, best of 3: 8.4 ms per loop >>> lis = [[1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0], [2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0], [1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0], [2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0]]*10**5 >>> %timeit set.intersection(*map(set, lis)) 1 loops, best of 3: 1.92 s per loop >>> %timeit set.intersection(*(set(e) for e in lis)) 1 loops, best of 3: 2.17 s per loop >>> %timeit reduce(set.intersection, map(set, lis)) 1 loops, best of 3: 2.14 s per loop >>> %timeit reduce(set.intersection, imap(set, lis)) 1 loops, best of 3: 1.52 s per loop >>> %timeit set.intersection(set(lis[0]), *islice(lis, 1, None)) 1 loops, best of 3: 913 ms per loop 

Conclusión:

La solución de Steven Rumbalski es claramente la mejor en términos de eficiencia.

La solución de Ashwini Chaudhary es elegante, pero podría ser bastante ineficiente para insumos grandes porque crea muchos conjuntos intermedios. Si tu lista nested_list es grande haz esto:

 >>> set.intersection(set(nested_list[0]), *itertools.islice(nested_list, 1, None)) set([2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0]) 

Prueba esto, es la solución más simple:

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

O si prefiere usar expresiones generadoras, que deberían ser una solución más eficiente en términos de uso de memoria:

 set.intersection(*(set(e) for e in nested_list)) 

Cuente las ocurrencias de cada elemento en los conjuntos de listas que aparecen en la lista anidada, si la ocurrencia es igual al número de elementos en la lista anidada, es común a todos. No necesita la conversión de conjuntos si los elementos de lista anidada no tienen números repetidos en ellos

 nested_list = [[1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0], [2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0], [1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0], [2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0]] from collections import Counter result = [val for val,cnt in Counter([x for t in nested_list for x in set(t)]).items() if cnt == len(nested_list)] print result # [2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0]