Что самый чистый путь состоит в том, чтобы сделать вид плюс uniq в списке Python?

Рассмотрите список 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()

55
задан olibre 2 October 2017 в 23:15
поделиться

5 ответов

my_list = sorted(set(my_list))
93
ответ дан 7 November 2019 в 07:16
поделиться

Другие упоминали 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 .

2
ответ дан 7 November 2019 в 07:16
поделиться

Не могу сказать, что это чистый способ сделать это, но просто для удовольствия:

my_list = [x for x in sorted(my_list) if not x in locals()["_[1]"]]
-5
ответ дан 7 November 2019 в 07:16
поделиться
# 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]]
16
ответ дан 7 November 2019 в 07:16
поделиться

Простое решение предоставлено Игнасио - sorted (set (foo)) .

Если у вас есть уникальные данные, есть разумная вероятность, что вы не просто захотите выполнить sorted (set (...)) , а скорее будете хранить набор все время и время от времени извлекать отсортированная версия значений. (В этот момент это начинает звучать так, как будто люди тоже часто используют базу данных.)

Если у вас есть отсортированный список, и вы хотите проверить членство по логарифмической шкале и добавить элемент в худшем случае по линейному времени, вы можете использовать модуль bisect .

Если вы хотите постоянно поддерживать это условие и хотите упростить некоторые операции или улучшить выполнение некоторых операций, вы можете рассмотреть blist.sortedset .

5
ответ дан 7 November 2019 в 07:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: