2016-02-10 8 views
13

Załóżmy, że mam kilka list liczb tak:znaleźć elementy, które występują w niektórych, ale nie wszystkich list

[0,3,4] 
[2,3,4,7] 
[2,3,4,6] 

Jaka jest najbardziej efektywne/większość pythonic sposób zbudować jedną listę wszystkich elementów, które występują w co przynajmniej jedna lista, ale nie występuje na wszystkich listach? W tym przypadku byłoby

[0,2,7,6] 
+1

można mieć powtarzające się elementy w tym samym liście? – SirParselot

+1

Czy kolejność jest ważna? –

+0

jeśli masz n list (i zakładając, że nie ma powtórzeń), chcesz, aby liczby występujące między 1 a n-1 razy na wszystkich listach były prawidłowe? –

Odpowiedz

6

Odpowiedź jest implikowana w swoim pytaniu .. jeśli zastąpić " ustaw "dla" list ". Jak napisał StephenTG, po prostu dostań różnicę między związkiem a przecięciem wszystkich list.

Zaletą korzystania z zestawów powyżej Counter jest to, że nie trzeba przyjmować założeń dotyczących wartości pojawiających się tylko raz na każdej liście.

następujące prace niezależnie od tego jak wiele list trzeba:

> list_of_sets = [set(l) for l in lists] 
> set.union(*list_of_sets) - set.intersection(*list_of_sets) 
{0, 2, 6, 7} 
4

Można podjąć przecięcie wszystkich listach jako zestaw, a Unia wszystkich listach jako zespół, i podejmują wszelkie elementy w Unii, które nie znajdują się na skrzyżowaniu . Istnieje union, intersection i difference metod do obsługi tego, że są udokumentowane here

>>> union_set = set(l1).union(l2,l3) 
>>> intersection_set = set(l1).intersection(l2,l3) 
>>> union_set - intersection_set 
set([0, 2, 6, 7]) 

Albo, jak kdopen pokazuje odpowiedzi, można utworzyć listę zestawów, jeśli nie znamy dokładnej liczby wykazów ty” Będziemy mieć do czynienia z

+2

Co zrobić, jeśli nie wiesz, ile z L1, L2, L3, ... może być? Czy na przykład można zastosować związek do listy list? –

+0

Dlatego wysłałem oddzielną odpowiedź – kdopen

+1

Wybrałem kdopena, ponieważ zostało napisane bardziej ogólnie, ale dzięki za to jedno –

4

Jeśli założymy, że każda lista zawiera co najwyżej jeden element, można użyć licznika do zliczenia liczby wystąpień każdego elementu. Następnie można wybrać elementy, które nie występują tyle razy, ile liczby list wejściowych:

from itertools import chain 
from collections import Counter 

lists = [ 
    [0, 3, 4], 
    [2, 3, 4, 7], 
    [2, 3, 4, 6] 
] 

print [x for x, c in Counter(chain(*lists)).items() if c != len(lists)] 

Wynik:

[0, 2, 6, 7] 
+0

To jest dokładnie to, co miałem napisać +1 – SirParselot

+0

To jest fajne, ale poszedłem z ogólnością dla wybranej odpowiedzi. –

+0

To będzie działać poprawnie, jeśli wewnętrzne listy nie zawierają powtarzających się elementów. –

Powiązane problemy