W tej odpowiedzi będą dwie sekcje: Dwa unikalne rozwiązania i wykres prędkości dla konkretnych rozwiązań.
Usuwanie zduplikowanych elementów
Większość z tych odpowiedzi usuwa tylko zduplikowane elementy, które można haszować , ale to pytanie nie oznacza, że nie tylko potrzebują haszowanych przedmiotów, co oznacza, że zaoferuję niektóre rozwiązania, które nie wymagają haszowania .
collections.Counter to potężne narzędzie w standardowej bibliotece, które może być do tego idealne. Jest tylko jedno inne rozwiązanie, które zawiera nawet Licznik. Jednak to rozwiązanie ogranicza się również do kluczy mieszalnych .
Aby zezwolić na klucze nieukrywalne w Counter, stworzyłem klasę Container, która spróbuje uzyskać domyślną funkcję skrótu obiektu, ale jeśli zawiedzie, spróbuje użyć funkcji tożsamości. Definiuje także metodę eq i metodę skrótu . To powinno wystarczyć, aby pozwolić naszym produktom na niewymagalne elementy. Obiekty, których nie można skasować, będą traktowane tak, jakby można je było haszować. Jednak ta funkcja skrótu używa tożsamości dla obiektów nieukończonych, co oznacza, że dwa równe obiekty, których oba są nieukończalne, nie będą działać. Sugeruję zastąpienie tego i zmianę go w celu użycia skrótu równoważnego typu zmiennego (np. Użycie hash(tuple(my_list))
if my_list
jest listą).
Stworzyłem również dwa rozwiązania. Kolejne rozwiązanie, które utrzymuje kolejność elementów, wykorzystując podklasę OrDERDict i Counter o nazwie „OrdersCounter”. Teraz oto funkcje:
from collections import OrderedDict, Counter
class Container:
def __init__(self, obj):
self.obj = obj
def __eq__(self, obj):
return self.obj == obj
def __hash__(self):
try:
return hash(self.obj)
except:
return id(self.obj)
class OrderedCounter(Counter, OrderedDict):
'Counter that remembers the order elements are first encountered'
def __repr__(self):
return '%s(%r)' % (self.__class__.__name__, OrderedDict(self))
def __reduce__(self):
return self.__class__, (OrderedDict(self),)
def remd(sequence):
cnt = Counter()
for x in sequence:
cnt[Container(x)] += 1
return [item.obj for item in cnt]
def oremd(sequence):
cnt = OrderedCounter()
for x in sequence:
cnt[Container(x)] += 1
return [item.obj for item in cnt]
remd to sortowanie bez uporządkowania, oremd to sortowanie uporządkowane. Możesz wyraźnie powiedzieć, który jest szybszy, ale i tak wyjaśnię. Nieuporządkowane sortowanie jest nieco szybsze. Przechowuje mniej danych, ponieważ nie potrzebuje porządku.
Teraz chciałem też pokazać porównanie prędkości dla każdej odpowiedzi. Zrobię to teraz.
Która funkcja jest najszybsza?
Do usuwania duplikatów zebrałem 10 funkcji z kilku odpowiedzi. Obliczyłem prędkość każdej funkcji i umieściłem ją na wykresie za pomocą matplotlib.pyplot .
Podzieliłem to na trzy rundy wykresów. Hashable to dowolny obiekt, który może być haszowany, hashable to każdy obiekt, który nie może być haszowany. Sekwencja uporządkowana to sekwencja, która zachowuje porządek, sekwencja nieuporządkowana nie zachowuje porządku. Oto kilka innych terminów:
Unordered Hashable był dla każdej metody, która usuwa duplikaty, co niekoniecznie musi zachowywać porządek. Nie musiało to działać na rzeczy nieskrępowane, ale mogło.
Uporządkowany Hashable był dla każdej metody, która zachowywała kolejność pozycji na liście, ale nie musiał działać dla nieusuwalnych, ale mógł.
Order Unhashable to dowolna metoda, która zachowuje porządek pozycji na liście i działa na niehashable.
Na osi y jest czas w sekundach.
Na osi X znajduje się liczba, do której zastosowano funkcję.
Wygenerowaliśmy sekwencje dla nieuporządkowanych skrótów i uporządkowanych skrótów z następującym zrozumieniem: [list(range(x)) + list(range(x)) for x in range(0, 1000, 10)]
W przypadku zamówionych elementów nieukończonych: [[list(range(y)) + list(range(y)) for y in range(x)] for x in range(0, 1000, 10)]
Zauważ, że w zakresie jest „krok”, ponieważ bez niego zajęłoby to 10 razy więcej. Również dlatego, że moim osobistym zdaniem myślałem, że może to wyglądać trochę łatwiej.
Zwróć też uwagę, że klawisze legendy są tym, co starałem się odgadnąć jako najbardziej istotne części funkcji. Co do funkcji, która jest najgorsza lub najlepsza? Wykres mówi sam za siebie.
Po ustaleniu, oto wykresy.
Nieuporządkowane haszysze
(Zbliżony)
Zamówione haszysze
(Zbliżony)
Zamówione Unhashables
(Zbliżony)