2010-06-01 11 views
6

jaki jest najłatwiejszy sposób na skrzyżowanie N-wielu list w pythonie?robienie przecięcia N-wielu list w pytonie

jeśli mam dwie listy A i B, wiem, że mogę zrobić:

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

ale chcę zrobić coś jak & b & c & d & ... dla dowolnego zbioru list (najlepiej, jeśli nie jest to konwersja do zestawu w pierwszej kolejności, ale jeśli jest to najłatwiejszy/najbardziej efektywny sposób, mogę sobie z tym poradzić.)

Tzn. Chcę napisać funkcję przecinającą się (* args), która zrobi to dla dowolnie wielu zestawów wydajnie. Jaki jest najłatwiejszy sposób na zrobienie tego?

EDYCJA: Moje własne rozwiązanie redukuje (setIntersection, [a, b, c]) - czy to jest dobre?

dzięki.

+0

W przypadku 'reduce()', nie jest to najlepszy pomysł, ponieważ jest on stopniowo wycofywany w Pythonie 3. Jest również wolniejszy, z tego, co słyszałem, w porównaniu do pętli for. –

+0

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

+0

@Xavier: 'from functools import reduce'. Został usunięty z 'builtins', nie jest całkowicie wycofany. Co więcej, to, co słyszałeś o jego prędkości, jest wysoce niedokładne: może być znacznie szybsze lub wolniejsze niż pętla for. – tzot

Odpowiedz

13

Działa to dla 1 lub więcej list. Pole listy 0 nie jest takie proste, ponieważ musiałoby zwrócić zestaw zawierający wszystkie możliwe wartości.

+0

Piękny. Naprawdę proste. –

+0

A zatem piękno korzystania z wbudowanych. – jathanism

2

Działa to 1 lub więcej list i nie korzysta z wielu parametrów:

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

Nie wiem, to jest lepsze niż inne odpowiedzi, w każdym razie.

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

Zestawy można przecinać z dowolnymi numerami, nie ma potrzeby przekształcania go w zestaw jako pierwszy.