У цій відповіді буде два розділи: Два унікальних рішення та графік швидкості для конкретних рішень.
Видалення повторюваних елементів
Більшість з цих відповідей видаляють лише дублікати елементів, які є хешируемими , але це питання не означає, що він не просто потребує хешируемих елементів, тобто я запропоную деякі рішення, які не потребують перебірливих елементів.
collection.Counter - це потужний інструмент у стандартній бібліотеці, який може бути ідеальним для цього. Є лише одне інше рішення, яке навіть має лічильник у ньому. Однак це рішення також обмежується доступними ключами.
Щоб дозволити незмінні ключі в Counter, я створив клас Container, який намагатиметься отримати хеш-функцію об'єкта за замовчуванням, але якщо він не вдасться, він спробує свою функцію ідентичності. Він також визначає еквівалентний і хеш- метод. Цього має бути достатньо, щоб дозволити невмирущі предмети в нашому рішенні. Незміцнілі предмети будуть розглядатися так, ніби вони підлягають перегляду. Однак ця хеш-функція використовує ідентичність для нездатних об'єктів, тобто два рівних об'єкти, які є нерозбірливими, не працюватимуть. Я пропоную вам переосмислити це та змінити його, щоб використовувати хеш еквівалентного типу, що змінюється (наприклад, hash(tuple(my_list))
якщо my_list
список є).
Я також прийняв два рішення. Ще одне рішення, яке підтримує порядок елементів, використовуючи підклас OrdersDict і Counter, який має назву "OrdersCounter". Тепер ось функції:
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 - це не упорядковане сортування, oremd - упорядковане сортування. Ви можете чітко сказати, хто з них швидший, але я все-таки поясню. Не упорядковане сортування трохи швидше. Він зберігає менше даних, оскільки не потребує порядку.
Тепер я також хотів показати порівняння швидкості кожної відповіді. Отже, я зараз це зроблю.
Яка функція найшвидша?
Для видалення дублікатів я зібрав 10 функцій із кількох відповідей. Я обчислював швидкість кожної функції і вкладав її у графік, використовуючи matplotlib.pyplot .
Я розділив це на три кола графіків. Хешируемость - це будь-який об'єкт, який можна хешировать, нерозбірливий - це будь-який об'єкт, який не можна хешировать. Впорядкована послідовність - це послідовність, яка зберігає порядок, не упорядкована послідовність не зберігає порядок. Тепер ось ще кілька термінів:
Не упорядкований Hashable був для будь-якого методу, який видаляв дублікати, які не обов'язково повинні були утримувати замовлення. Він не повинен був працювати на unhashables, але це міг.
Замовлений Hashable був для будь-якого методу, який підтримував порядок елементів у списку, але він не повинен працювати для unhashables, але він міг.
Замовлений Unhashable - це будь-який метод, який підтримував порядок позицій у списку та працював на unhashables.
На осі у - кількість секунд, які знадобилися.
На осі x - це число, до якого застосовувалася функція.
Ми створили послідовності для не упорядкованих хешбелів та замовили хешбелі з наступним розумінням: [list(range(x)) + list(range(x)) for x in range(0, 1000, 10)]
Для замовлених unhashables: [[list(range(y)) + list(range(y)) for y in range(x)] for x in range(0, 1000, 10)]
Зауважте, що в діапазоні є "крок", тому що без цього це займе 10 разів. Також тому, що, на мою особисту думку, я думав, що це, можливо, виглядало трохи легше для читання.
Також зауважте, що клавіші легенди - це те, що я намагався здогадатися як найважливіші частини функції. Щодо того, яку функцію виконує найгірша чи найкраща? Графік говорить сам за себе.
З урахуванням цього, ось графіки.
Не упорядковані мішалки
(Збільшення масштабу)
Впорядковані гашені вироби
(Збільшення масштабу)
Замовлені Unhashables
(Збільшення масштабу)