У вас здесь есть несколько слегка расточительных шагов, но ваше предложение в значительной степени верно.Единственные реальные улучшения, которые необходимо сделать, - это избавиться от всех ненужных временных list
s:
new_list = sorted(set(orig_list), reverse=True)
sorted
уже преобразует свои входные данные в list
(поэтому нет необходимости list
перед переходом к sorted
), и вы можете получить его непосредственно для вывода list
, отсортированного в обратном порядке (поэтому не нужно создавать list
только для того, чтобы сделать его копию в обратном порядке).
Единственное мыслимое улучшение времени big-O - это если вы знаете данные уже отсортированы, и в этом случае вы можете избежать сортировки O(n log n)
и выполнить uniqify без потери существующего порядка сортировки на , используяitertools.groupby
:
new_list = [key for key, grp in itertools.groupby(orig_list)]
Если orig_list
отсортировано в прямом порядке, вы можете изменить результат без каких-либо затрат, изменив itertools.groupby(orig_list)
на itertools.groupby(reversed(orig_list))
.
Решение groupby
не очень практично для изначально несортированных входов, потому что, если дубликаты распространены даже удаленно, удаление их с помощью уникального кода как шага O(n)
почти всегда того стоит, так как уменьшает n
в более дорогойу O(n log n)
шаг сортировки.groupby
также является относительно медленным инструментом;Характер реализации, использующей кучу временных итераторов для каждой группы, внутреннее кэширование значений и т. д., означает, что на практике это медленнее O(n)
, чем унификация O(n)
через set
, причем его основным преимуществом являетсяаспект потоковой передачи (масштабирование до наборов данных, передаваемых с диска или из сети и обратно без долгосрочного хранения, где set
должно вытянуть все в память).
Другая причина использовать sorted
+ groupby
было бы, если бы ваши данные не были хэшируемыми, но были сопоставимы;в этом случае set
не вариант, поэтому единственный выбор - сортировка и группировка.