2010-10-04 8 views
36

gram z python i jestem w stanie uzyskać punkt przecięcia dwóch list:Python - Intersekcja wielu list?

result = set(a).intersection(b) 

Teraz jeśli d jest lista zawierająca a i b i trzeci element c, to istnieje funkcja wbudowana w celu znalezienia przecięcie wszystkich trzech list wewnątrz d? Tak na przykład,

d = [[1,2,3,4], [2,3,4], [3,4,5,6,7]] 

wtedy wynik powinien być

[3,4] 

Odpowiedz

33

do 2.4, można po prostu zdefiniować funkcję przecięcia.

def intersect(*d): 
    sets = iter(map(set, d)) 
    result = sets.next() 
    for s in sets: 
     result = result.intersection(s) 
    return result 

nowsze wersje Pythona:

metoda przecięcia wykonuje dowolną ilość argumentów

result = set(d[0]).intersection(*d[:1]) 

alternatywnie można przecinać pierwszy zestaw ze sobą, aby uniknąć krojenia lista i wykonanie kopii:

result = set(d[0]).intersection(*d) 

Nie jestem pewien, co byłoby bardziej efektywne i mają poczucie, że to zależy od wielkości d[0] i wielkości listy, chyba że Python posiada wbudowaną czek na nim jak

if s1 is s2: 
    return s1 

w metoda skrzyżowania.

>>> d = [[1,2,3,4], [2,3,4], [3,4,5,6,7]] 
>>> set(d[0]).intersection(*d) 
set([3, 4]) 
>>> set(d[0]).intersection(*d[1:]) 
set([3, 4]) 
>>> 
+0

@AaronMcSmooth: It daje me 'AttributeError: 'list' obiekt nie ma atrybutu" przecięcie ", jeśli to zrobię. Czy czegoś brakuje? – Legend

+0

@Legend. najpierw musisz zmapować go do zestawu. W jakiś sposób przegapiłem fakt, że były to listy.Potem możesz po prostu przekazać listy (lub inne iterowalne) do metody 'przecięcia ' – aaronasterling

+0

@AaronMcSmooth: Właściwie nie wiem dlaczego, ale otrzymuję ten błąd bez względu na to, jakie rozwiązanie wypróbuję:' TypeError: intersection() takes dokładnie jeden argument (podany 3) ' – Legend

40
set.intersection(*map(set,d)) 
+0

Nie jestem pewien, co jest nie tak. Teraz daje mi: 'TypeError: crosssement() ma dokładnie jeden argument (2 dany)' – Legend

+0

@Legend, w jakiej wersji pytona jesteś? mi to pasuje. – aaronasterling

+0

@AaronMcSmooth: 2.4.3? – Legend

2

Lambda zmniejszyć.

from functools import reduce #you won't need this in Python 2 
reduce(set.intersection, [[1, 2, 3, 4], [2, 3, 4], [3, 4, 5, 6, 7]]) 
+0

potrzebujesz listy zestawów, nie powiedzie się, że "skrzyżowanie deskryptorów wymaga zestawu" – tj89

2

@ user3917838

Ładne i proste, ale wymaga pewnych odlew, aby pracować i dać listę wyniku. Powinno to wyglądać tak:

list(reduce(set.intersection, [set(item) for item in d ]))

gdzie:

d = [[1,2,3,4], [2,3,4], [3,4,5,6,7]]

i rezultat:

[3, 4]

Przynajmniej w Pythonie 3.4