Wszystkie poniższe odpowiedzi wydają mi się błędne. Co się stanie, jeśli liczba zostanie powtórzona na którejkolwiek z list, z pewnością chcesz wiedzieć, że (?) (Np. Powiedzmy, że obie listy mają „5” dwa razy) Każde rozwiązanie wykorzystujące zestawy natychmiast usunie wszystkie powtarzane elementy i stracisz ta informacja.
Uwaga uwaga, lista jest zrozumienie nie koniecznie szybsza opcja. W przypadku większych zestawów (gdzie wydajność najprawdopodobniej będzie miała znaczenie) porównanie bitowe ( &) lub set(a).intersection(b)będzie tak samo szybkie lub szybsze jak zrozumienie listy.
Joshmaker
24
Kolejna uwaga: na podstawie listy znajduje się wartość, która pojawia się zarówno na SAMYCH pozycjach (to właśnie SilentGhost rozumie przez „porządek jest znaczący”). Rozwiązania dotyczące skrzyżowań znajdą również dopasowania na INNYCH pozycjach. To są odpowiedzi na 2 zupełnie różne pytania ... (pytanie op jest niejednoznaczne, o które pyta)
drevicko
Jak to zrobić, jeśli listy są listami, tj. A = [[0,0], [1,0]] ib = [[2,3], [0,0]]
Schneems,
3
Jaka byłaby złożoność czasowa pierwszego przykładu set(a) & set(b)?
AdjunctProfessorFalcon
Uwaga: to nie działa, jeśli oba zestawy są puste i oczekuje się, że porównanie się powiedzie. Więc zmień na „(zestaw (a) i zestaw (b)) lub (nie a i nie b)”
Ta odpowiedź ma dobrą wydajność algorytmiczną, ponieważ tylko jedna z list (powinna być preferowana krótsza) jest zamieniana w zestaw do szybkiego wyszukiwania, a druga lista jest przeglądana w poszukiwaniu jej elementów w zestawie.
u0b34a0f6ae
18
bool(set(a).intersection(b))for TrueorFalse
Akshay,
6
Ta odpowiedź jest bardziej elastyczna i czytelna, ponieważ ludzie mogą potrzebować differencelub union.
Shihe Zhang,
Co jeśli mam obiekty jako elementy listy i chcę tylko częściowe dopasowania, tj. Tylko niektóre atrybuty muszą się zgadzać, aby można je było uznać za pasujący obiekt?
CGFoX
Czy jest jakaś różnica w wydajności dla .intersection()vs &?
brandonbanks,
106
Szybki test wydajności pokazujący rozwiązanie Lutza jest najlepszy:
import time
def speed_test(func):def wrapper(*args,**kwargs):
t1 = time.time()for x in xrange(5000):
results = func(*args,**kwargs)
t2 = time.time()print'%s took %0.3f ms'%(func.func_name,(t2-t1)*1000.0)return results
return wrapper
@speed_testdef compare_bitwise(x, y):
set_x = frozenset(x)
set_y = frozenset(y)return set_x & set_y
@speed_testdef compare_listcomp(x, y):return[i for i, j in zip(x, y)if i == j]@speed_testdef compare_intersect(x, y):return frozenset(x).intersection(y)# Comparing short lists
a =[1,2,3,4,5]
b =[9,8,7,6,5]
compare_bitwise(a, b)
compare_listcomp(a, b)
compare_intersect(a, b)# Comparing longer listsimport random
a = random.sample(xrange(100000),10000)
b = random.sample(xrange(100000),10000)
compare_bitwise(a, b)
compare_listcomp(a, b)
compare_intersect(a, b)
Oto wyniki na moim komputerze:
# Short list:
compare_bitwise took 10.145 ms
compare_listcomp took 11.157 ms
compare_intersect took 7.461 ms
# Long list:
compare_bitwise took 11203.709 ms
compare_listcomp took 17361.736 ms
compare_intersect took 6833.768 ms
Oczywiście, każdy test sztucznej wydajności powinien być wykonywany z ziarenkiem soli, ale ponieważ set().intersection()odpowiedź jest co najmniej tak szybka jak inne rozwiązania, a także najbardziej czytelna, powinna być standardowym rozwiązaniem tego powszechnego problemu.
Zestaw faktycznie usuwa powtórzenia, więc w moim przypadku nie zadziała
rgralma
@rgralma dokonanie nowego setz istniejącego listnie usunie niczego z oryginału list. Jeśli chcesz, aby specjalna logika obsługiwała duplikaty na liście, myślę, że musisz zadać nowe pytanie, ponieważ odpowiedź będzie musiała być specyficzna dla tego, jak chcesz obsługiwać duplikaty.
Joshmaker
67
Wolę odpowiedzi oparte na zestawie, ale tutaj i tak działa
Według doc - ... wyklucza podatne na błędy konstrukcje, takie jak Set („abc”) i „cbs” na korzyść bardziej czytelnego zestawu („abc”). Przecięcie („cbs”). - docs.python.org/library/sets.html
Aaron Newton
5
innym nieco bardziej funkcjonalnym sposobem sprawdzenia równości listy dla listy 1 (Ist1) i listy 2 (IST2), gdzie obiekty mają głębokość 1 i która zachowuje kolejność, jest:
Chociaż ten kod może odpowiedzieć na pytanie, zapewnienie dodatkowego kontekstu dotyczącego tego, jak i / lub dlaczego rozwiązuje problem, poprawiłoby długoterminową wartość odpowiedzi.
Kaczor Donald
4
Może również używać itertools.product.
>>> common_elements=[]>>>for i in list(itertools.product(a,b)):...if i[0]== i[1]:... common_elements.append(i[0])
you can |for set union and&for set intersection.for example:
set1={1,2,3}
set2={3,4,5}print(set1&set2)
output=3
set1={1,2,3}
set2={3,4,5}print(set1|set2)
output=1,2,3,4,5
curly braces in the answer.
Odpowiedzi:
Nie najskuteczniejszy, ale zdecydowanie najbardziej oczywisty sposób to:
jeśli kolejność jest znacząca, możesz to zrobić za pomocą następujących pojęć:
(działa tylko w przypadku list o jednakowej wielkości, co sugeruje znaczenie kolejności).
źródło
&
) lubset(a).intersection(b)
będzie tak samo szybkie lub szybsze jak zrozumienie listy.set(a) & set(b)
?Użyj set.intersection () , jest szybki i czytelny.
źródło
bool(set(a).intersection(b))
forTrue
orFalse
difference
lubunion
..intersection()
vs&
?Szybki test wydajności pokazujący rozwiązanie Lutza jest najlepszy:
Oto wyniki na moim komputerze:
Oczywiście, każdy test sztucznej wydajności powinien być wykonywany z ziarenkiem soli, ale ponieważ
set().intersection()
odpowiedź jest co najmniej tak szybka jak inne rozwiązania, a także najbardziej czytelna, powinna być standardowym rozwiązaniem tego powszechnego problemu.źródło
set
z istniejącegolist
nie usunie niczego z oryginałulist
. Jeśli chcesz, aby specjalna logika obsługiwała duplikaty na liście, myślę, że musisz zadać nowe pytanie, ponieważ odpowiedź będzie musiała być specyficzna dla tego, jak chcesz obsługiwać duplikaty.Wolę odpowiedzi oparte na zestawie, ale tutaj i tak działa
źródło
Najprostszym sposobem na to jest użycie zestawów :
źródło
Szybki sposób:
źródło
źródło
Możesz także tego spróbować, utrzymując wspólne elementy na nowej liście.
źródło
Czy chcesz duplikaty? Jeśli nie, możesz zamiast tego użyć zestawów:
źródło
innym nieco bardziej funkcjonalnym sposobem sprawdzenia równości listy dla listy 1 (Ist1) i listy 2 (IST2), gdzie obiekty mają głębokość 1 i która zachowuje kolejność, jest:
źródło
źródło
Może również używać itertools.product.
źródło
Możesz użyć
źródło
Możesz użyć:
Wynik:
źródło
Jeśli chcesz wartość logiczną:
źródło
Poniższe rozwiązanie działa dla dowolnej kolejności elementów listy, a także obsługuje obie listy o różnej długości.
źródło
np.intersect1d(list1, list2)
Korzystanie
__and__
metoda działa również atrybut.lub po prostu
źródło
źródło
&
operatora na planie jest już odpowiedzią SilentGhost w zaakceptowanej odpowiedziWłaśnie użyłem następujących i zadziałało to dla mnie:
spowoduje to wydrukowanie 5 w twoim przypadku. Prawdopodobnie nie pod względem wydajności.
źródło