Na przykład, biorąc pod uwagę listę ['one', 'two', 'one']
, algorytm powinien zwrócić True
, a biorąc pod uwagę, ['one', 'two', 'three']
że powinien zwrócić False
.
python
string
list
duplicates
teggy
źródło
źródło
Zalecane tylko dla krótkich list:
Czy nie używać na długiej liście - może to potrwać proporcjonalna do kwadratu liczby pozycji na liście!
W przypadku dłuższych list z elementami haszującymi (ciągi, liczby i c):
Jeśli twoich przedmiotów nie da się ukryć (listy podrzędne, dykta itp.), Staje się bardziej włochaty, choć nadal można uzyskać O (N logN), jeśli są co najmniej porównywalne. Ale musisz znać lub przetestować właściwości elementów (możliwe do skrótu lub nie, porównywalne lub nie), aby uzyskać najlepszą możliwą wydajność - O (N) w przypadku skrótów, O (N log N) w przypadku nieudanych skrótów, w przeciwnym razie zależy od O (N do kwadratu) i nic nie można na to poradzić :-(.
źródło
all
wszystkie liczyły się jako 1). Dykt ze wszystkimi wartościami Prawda, o którym również wspominasz, jest absurdalnie, bezużyteczną naśladownictwemset
, bez żadnej wartości dodanej. Big-O to nie wszystko w programowaniu.To stare, ale odpowiedzi tutaj doprowadziły mnie do nieco innego rozwiązania. Jeśli jesteś skłonny do nadużywania rozumienia, możesz w ten sposób doprowadzić do zwarcia.
źródło
Jeśli lubisz funkcjonalny styl programowania, oto przydatna funkcja, samodokumentowany i przetestowany kod za pomocą doctest .
Stamtąd możesz przetestować niepowtarzalność, sprawdzając, czy drugi element zwracanej pary jest pusty:
Zauważ, że nie jest to wydajne, ponieważ jawnie konstruujesz rozkład. Ale zgodnie z zasadą zmniejszania można uzyskać coś równoważnego (ale nieco mniej wydajnego), aby odpowiedzieć 5:
źródło
Pomyślałem, że przydałoby się porównać terminy różnych przedstawionych tutaj rozwiązań. Do tego użyłem własnej biblioteki
simple_benchmark
:Rzeczywiście, w tym przypadku rozwiązanie Denisa Otkidacha jest najszybsze.
Niektóre z podejść wykazują również znacznie bardziej stromą krzywą, są to podejścia, które skalują się kwadratowo z liczbą elementów (pierwsze rozwiązanie Alexa Martellisa, wjandrea i oba rozwiązania Xaviera Decoretsa). Należy również wspomnieć, że rozwiązanie pand z Keiku ma bardzo duży stały czynnik. Ale w przypadku większych list prawie dogania inne rozwiązania.
W przypadku, gdy duplikat znajduje się na pierwszej pozycji. Jest to przydatne, aby zobaczyć, które rozwiązania powodują zwarcie:
Tutaj kilka podejść nie powoduje zwarcia: Kaiku, Frank, Xavier_Decoret (pierwsze rozwiązanie), Turn, Alex Martelli (pierwsze rozwiązanie) i podejście przedstawione przez Denisa Otkidacha (który był najszybszy w przypadku bez duplikatów).
Dołączyłem tutaj funkcję z własnej biblioteki:
iteration_utilities.all_distinct
która może konkurować z najszybszym rozwiązaniem w przypadku braku duplikatów i działa w stałym czasie dla przypadku duplikowania na początku (choć nie tak szybko).Kod testu porównawczego:
A dla argumentów:
źródło
Niedawno odpowiedziałem na powiązane pytanie, aby ustalić wszystkie duplikaty na liście za pomocą generatora. Ma tę zaletę, że jeśli zostanie użyte tylko do ustalenia „jeśli jest duplikat”, wystarczy zdobyć pierwszy przedmiot, a resztę można zignorować, co jest ostatecznym skrótem.
Jest to interesujące podejście oparte na zestawie, które zaadaptowałem prosto z moooeeeep :
W związku z tym byłaby pełna lista duplikatów
list(getDupes(etc))
. Aby po prostu przetestować „jeśli” istnieje duplikat, należy go owinąć w następujący sposób:To dobrze się skaluje i zapewnia stały czas działania wszędzie tam, gdzie duplikat znajduje się na liście - testowałem z listami do 1m wpisów. Jeśli wiesz coś o danych, w szczególności o tym, że duplikaty najprawdopodobniej pojawią się w pierwszej połowie, lub o innych rzeczach, które pozwolą ci zmienić wymagania, na przykład konieczność uzyskania rzeczywistych duplikatów, istnieje kilka naprawdę alternatywnych lokalizatorów duplikatów to może przewyższyć. Dwa polecam to ...
Proste podejście oparte na nagraniu, bardzo czytelne:
Wykorzystaj narzędzia itertools (zasadniczo ifilter / izip / tee) na posortowanej liście, bardzo wydajne, jeśli otrzymujesz wszystkie duplikaty, ale nie tak szybko, aby uzyskać tylko pierwszy:
Były to najlepsze wyniki z podejść, które próbowałem uzyskać pełną listę duplikatów , przy czym pierwszy duplikat występował w dowolnym miejscu na liście elementów o długości 1 m od początku do środka. Zaskakujące było to, jak niewiele wrzucił krok sortowania. Twój przebieg może się różnić, ale oto moje konkretne wyniki czasowe:
źródło
.next()
Wezwanie w drugim bloku kodu nie działa na Python 3.x. Myślę, żenext(getDupes(l))
powinien działać w różnych wersjach Pythona, więc warto to zmienić.ifilter
iìzip
może być po prostu zastąpione przez wbudowanyfilter
orazzip
w Pythonie 3.x.Innym sposobem robienia tego zwięźle jest Counter .
Aby ustalić, czy na oryginalnej liście są jakieś duplikaty:
Lub uzyskać listę elementów, które mają duplikaty:
źródło
źródło
Stwierdziłem, że zapewnia to najlepszą wydajność, ponieważ powoduje zwarcie operacji, gdy znaleziono pierwszą kopię, a następnie algorytm ten ma złożoność czasową i przestrzenną O (n), gdzie n jest długością listy:
źródło
Naprawdę nie wiem, co robi zestaw za kulisami, więc po prostu lubię to upraszczać.
źródło
Prostsze rozwiązanie jest następujące. Po prostu sprawdź True / False
.duplicated()
metodą pandy , a następnie zbierz sumę. Zobacz także dokumentację pandas.Series.duplicated - panda 0.24.1źródło
Jeśli lista zawiera elementy nieukrywalne, możesz użyć rozwiązania Alexa Martellego, ale z listą zamiast zestawu, chociaż jest wolniejsza dla większych danych wejściowych: O (N ^ 2).
źródło
Użyłem podejścia pirospade ze względu na jego prostotę i zmodyfikowałem go nieco na krótkiej liście z rejestru Windows bez rozróżniania wielkości liter.
Jeśli nieprzetworzony ciąg wartości PATH zostanie podzielony na poszczególne ścieżki, wszystkie ścieżki „puste” (ciągi puste lub tylko białe znaki) można usunąć za pomocą:
Oryginalna ścieżka zawiera zarówno „zerowe” wpisy, jak i duplikaty do celów testowych:
Ścieżki zerowe zostały usunięte, ale nadal mają duplikaty, np. (1, 3) i (13, 20):
I wreszcie duplikaty zostały usunięte:
źródło
źródło