Najpopularniejszymi odpowiedziami są O (N) (dobrze! -), ale, jak zaznaczają @Paul i @Mark, wymagają, aby elementy listy były nieosiągalne. Zarówno proponowane podejścia @Paul, jak i @ Mark do nieuszkodzonych przedmiotów są ogólne, ale przyjmują O (N do kwadratu) - tj. Dużo.
Jeśli pozycje na liście nie dają się przetłumaczyć, ale są porównywalne, można zrobić lepiej ... oto podejście, które zawsze działa tak szybko, jak to możliwe, biorąc pod uwagę charakter elementów listy.
import itertools
def allunique(L):
# first try sets -- fastest, if all items are hashable
try:
return len(L) == len(set(L))
except TypeError:
pass
# next, try sort -- second fastest, if items are comparable
try:
L1 = sorted(L)
except TypeError:
pass
else:
return all(len(list(g))==1 for k, g in itertools.groupby(L1))
# fall back to the slowest but most general approach
return all(v not in L[i+1:] for i, L in enumerate(L))
Jest to O (N), gdzie to możliwe (wszystkie pozycje hashable), O (N log N) jako najczęstsza awaryjnej (niektóre elementy unhashable, ale porównywalne), O (N kwadratu), gdzie nieuniknione (niektóre elementy nie nadające się do użytku, np. dyktuje, a niektóre nieporównywalne, np. liczby zespolone).
Inspiracja dla tego kodu pochodzi ze starej receptury autorstwa wielkiego Tima Petersa, która różniła się tym, że rzeczywiście tworzy listę unikatowych przedmiotów (a także było tak dawno temu, że w pobliżu nie było set
- musiało użyć dict
. ..! -), ale zasadniczo napotkał identyczne problemy.
Bardzo mądra odpowiedź – foosion
Po prostu mógł je przechowywać w zestawie w pierwszej kolejności, aby upewnić się, że wszystkie one są unikalne. Lub zapisz je w zestawie, ale przed dodaniem do zestawu sprawdź członkostwo. Ale to na pewno działa, jeśli nie masz kontroli nad formatem wejściowym. –
zestawy niekoniecznie zachowują kolejność, która może być ważna. –