Ответ 1
my_list = sorted(set(my_list))
Рассмотрим список Python my_list
, содержащий ['foo', 'foo', 'bar']
.
Каков самый питоновский способ uniquify и отсортировать список?
(подумайте cat my_list | sort | uniq
)
Вот как я это делаю сейчас, и пока он работает, я уверен, что есть лучшие способы сделать это.
my_list = []
...
my_list.append("foo")
my_list.append("foo")
my_list.append("bar")
...
my_list = set(my_list)
my_list = list(my_list)
my_list.sort()
my_list = sorted(set(my_list))
# Python ≥ 2.4
# because of (generator expression) and itertools.groupby, sorted
import itertools
def sort_uniq(sequence):
return (x[0] for x in itertools.groupby(sorted(sequence)))
Быстрее
import itertools, operator
import sys
if sys.hexversion < 0x03000000:
mapper= itertools.imap # 2.4 ≤ Python < 3
else:
mapper= map # Python ≥ 3
def sort_uniq(sequence):
return mapper(
operator.itemgetter(0),
itertools.groupby(sorted(sequence)))
Обе версии возвращают генератор, поэтому вы можете отправить результат в тип списка:
sequence= list(sort_uniq(sequence))
Обратите внимание, что это также будет работать с не-хэшируемыми элементами:
>>> list(sort_uniq([[0],[1],[0]]))
[[0], [1]]
Прямое решение предоставляется Игнасио sorted(set(foo))
.
Если у вас есть уникальные данные, есть разумный шанс, что вы просто не хотите делать sorted(set(...))
, а скорее хранить набор все время и иногда вытаскивать отсортированную версию значений. (В этот момент он начинает звучать так, как будто люди часто используют базу данных тоже.)
Если у вас есть отсортированный список, и вы хотите проверить членство на логарифмическом и добавить элемент в наихудшем линейном времени, вы можете использовать модуль bisect
.
Если вы хотите постоянно сохранять это условие и хотите упростить ситуацию или сделать некоторые операции более эффективными, вы можете рассмотреть blist.sortedset
.
Другие упомянули отсортированный (set (my_list)), который работает для хэшируемых значений, таких как строки, числа и кортежи, но не для нераспаковываемых типов, таких как списки.
Чтобы получить отсортированный список значений любого сортируемого типа без дубликатов:
from itertools import izip, islice
def unique_sorted(values):
"Return a sorted list of the given values, without duplicates."
values = sorted(values)
if not values:
return []
consecutive_pairs = izip(values, islice(values, 1, len(values)))
result = [a for (a, b) in consecutive_pairs if a != b]
result.append(values[-1])
return result
Это может быть дополнительно упрощено с помощью рецептов "попарно" или "unique_justseen" из документации itertools.
Не могу сказать, что это чистый способ сделать это, но просто для удовольствия:
my_list = [x for x in sorted(my_list) if not x in locals()["_[1]"]]