Рассмотрите список Python my_list
содержа ['foo', 'foo', 'bar']
.
Какова большая часть Pythonic путь к 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()
Другие упоминали sorted (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]"]]
# 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)))
Обе версии возвращают генератор, так что вы можете захотеть передать результат типу list:
sequence= list(sort_uniq(sequence))
Обратите внимание, что это будет работать и с нехэшируемыми элементами:
>>> list(sort_uniq([[0],[1],[0]]))
[[0], [1]]
Простое решение предоставлено Игнасио - sorted (set (foo))
.
Если у вас есть уникальные данные, есть разумная вероятность, что вы не просто захотите выполнить sorted (set (...))
, а скорее будете хранить набор все время и время от времени извлекать отсортированная версия значений. (В этот момент это начинает звучать так, как будто люди тоже часто используют базу данных.)
Если у вас есть отсортированный список, и вы хотите проверить членство по логарифмической шкале и добавить элемент в худшем случае по линейному времени, вы можете использовать модуль bisect
.
Если вы хотите постоянно поддерживать это условие и хотите упростить некоторые операции или улучшить выполнение некоторых операций, вы можете рассмотреть blist.sortedset
.