a = [1,2,3,4,5]
b = [1,3,5,6]
c = a and b
print c
rzeczywista wydajność: [1,3,5,6]
oczekiwana wydajność:[1,3,5]
Jak możemy uzyskać operację logiczną AND (przecięcie listy) na dwóch listach?
python
arrays
intersection
csguy11
źródło
źródło
a and b
działa tak, jak wspomina to następująca instrukcja z dokumentacji : „ Wyrażeniex and y
najpierw oceniax
; jeślix
jest fałszywe, jego wartość jest zwracana; w przeciwnym raziey
jest oceniana, a wynikowa wartość jest zwracana. ”Odpowiedzi:
Jeśli kolejność nie jest ważna i nie musisz się martwić o duplikaty, możesz użyć ustawienia skrzyżowania:
źródło
a = [1,1,2,3,4,5]
ib = [1,1,3,5,6]
wtedy skrzyżowanie jest,[1,1,3,5]
ale powyższa metoda spowoduje tylko jeden,1
tj.[1, 3, 5]
jaki będzie wtedy sposób zapisu?intersection
jest powszechnie rozumiany jako oparty na ustawieniach . Szukasz nieco innego zwierzęcia - być może będziesz musiał to zrobić ręcznie, sortując każdą listę i łącząc wyniki - i utrzymując dups w łączeniu.Używanie wyrażeń listowych jest dla mnie dość oczywiste. Nie jestem pewien co do wydajności, ale przynajmniej rzeczy pozostają listami.
[x for x in a if x in b]
Lub „wszystkie wartości x, które są w A, jeśli wartość X jest w B”.
źródło
b
zestaw, a będziesz mieć O (n)Jeśli przekształcisz większą z dwóch list w zestaw, możesz uzyskać skrzyżowanie tego zestawu z dowolnym iterowalnym przy użyciu
intersection()
:źródło
list(set(a) & set(b))
Zrób zestaw z większego:
Następnie,
zrobi to, co chcesz (zachowując
b
porządek, a niea
- niekoniecznie zachowa oba ) i zrobi to szybko . (Używanieif x in a
jako warunku w zrozumieniu listy również działałoby i pozwalało uniknąć konieczności budowania_auxset
, ale niestety w przypadku list o znacznej długości byłoby to znacznie wolniejsze).Jeśli chcesz posortować wynik, a nie zachowywać kolejność list, jeszcze lepszym sposobem może być:
źródło
Oto trochę kodu Python 2 / Python 3, który generuje informacje o taktowaniu zarówno dla metod opartych na listach, jak i na zestawach, służących do znalezienia przecięcia dwóch list.
Algorytmy rozumienia czystej listy to O (n ^ 2), ponieważ
in
na liście jest wyszukiwanie liniowe. Algorytmy oparte na zestawie to O (n), ponieważ wyszukiwanie zestawu to O (1), a tworzenie zestawu to O (n) (a konwersja zestawu na listę to także O (n)). Tak więc dla wystarczająco dużego n algorytmy oparte na zestawie są szybsze, ale w przypadku małych n nakłady związane z tworzeniem zestawu powodują, że są one wolniejsze niż algorytmy kompresji z czystej listy.wynik
Wygenerowano przy użyciu jednordzeniowego komputera 2GHz z 2 GB pamięci RAM z uruchomionym Pythonem 2.6.6 w systemie Linux Debian (z Firefoxem działającym w tle).
Liczby te są jedynie orientacyjnymi wskazówkami, ponieważ na rzeczywiste prędkości różnych algorytmów wpływa w różny sposób proporcja elementów znajdujących się na obu listach źródeł.
źródło
Powinien działać jak sen. I jeśli możesz, używaj zestawów zamiast list, aby uniknąć zmiany tego typu!
źródło
Funkcjonalny sposób można osiągnąć za pomocą
filter
ilambda
operatora.Edycja: Filtruje x, który istnieje zarówno na list1, jak i na liście, ustawioną różnicę można również osiągnąć za pomocą:
Edycja2: python3
filter
zwraca obiekt filtru, hermetyzując go,list
zwraca listę wyników.źródło
list(filter(lambda x:x in list1, list2))
aby uzyskać go jako listę.Jest to przykład, kiedy potrzebujesz Każdy element w wyniku powinien pojawić się tyle razy, ile pokazuje w obu tablicach.
źródło
Może być późno, ale pomyślałem, że powinienem podzielić się tym przypadkiem, w którym musisz to zrobić ręcznie (pokaż działanie - haha) LUB gdy potrzebujesz, aby wszystkie elementy pojawiały się tyle razy, ile to możliwe, lub gdy potrzebujesz, aby były unikalne .
Uprzejmie informujemy, że zostały również napisane testy.
źródło
Jeśli przez Boolean AND masz na myśli elementy, które pojawiają się na obu listach, np. Skrzyżowanie, powinieneś spojrzeć na Pythona
set
ifrozenset
typy.źródło
Możesz także użyć licznika! Nie zachowuje kolejności, ale weźmie pod uwagę duplikaty:
źródło