2010-06-01 19 views
6

¿Cuál es la forma más fácil de tomar la intersección de N-many lists en python?tomando la intersección de N-many listas en python

si tengo dos listas A y B, sé que puedo hacer:

a = set(a) 
b = set(b) 
intersect = a.intersection(b) 

pero quiero hacer algo como un & & b c d & & ... de un conjunto arbitrario de las listas (idealmente sin convertir a un conjunto primero, pero si esa es la forma más fácil/más eficiente, puedo lidiar con eso.)

Ie Quiero escribir una función intersecar (* args) que lo hará arbitrariamente para muchos conjuntos de manera eficiente. ¿Cuál es la forma más fácil de hacer eso?

EDITAR: Mi propia solución es reducir (set.intersection, [a, b, c]) - ¿eso es bueno?

gracias.

+0

En 'reducir()', no es precisamente la mejor idea, ya que está siendo eliminado en Python 3. También es más lento, por lo que he oído, en comparación con un bucle. –

+0

Duplicado: http://stackoverflow.com/questions/2893500/take-the-intersection-of-an-arbitrary-number-of-lists-in-python –

+0

@Xavier: 'from functools import reduce'. Se elimina de los 'builtins', no se elimina por completo. Además, lo que has escuchado sobre su velocidad es muy impreciso: puede ser mucho más rápido o más lento que un bucle for. – tzot

Respuesta

13

Esto funciona para 1 o más listas. El caso de 0 listas no es tan fácil, porque tendría que devolver un conjunto que contenga todos los valores posibles.

def intersection(first, *others): 
    return set(first).intersection(*others) 
+0

Hermoso. Realmente simple –

+0

Y, por tanto, la belleza de usar integradas. – jathanism

2

Esto funciona con 1 o más listas y no utiliza múltiples parámetros:

>>> def intersection(*listas): 
...  return set(listas[0]).intersection(*listas[1:]) 
...  
>>> intersection([1,2,3,4],[4,5,6],[2,4,5],[1,4,8]) 
set([4]) 
>>> intersection([1,2,3,4]) 
set([1, 2, 3, 4]) 
>>> 
No

seguro de que esto es mejor que otras respuestas, de todos modos.

2
lists = [[5,4,3], [4,2], [6,2,3,4]] 

try: 
    # the following line makes one intersection too much, but I don't think 
    # this hurts performance noticably. 
    intersected = set(lists[0]).intersection(*lists) 
except ValueError: 
    # no lists[0] 
    intersected = set() 

print intersected   # set([4]) 

Los conjuntos se pueden intersecar con cualquier iterable, no es necesario convertirlo primero en un conjunto.

Cuestiones relacionadas