Как правильно использовать SortedSets по ключу в Python sortedcontainers


SortedListWithKey может сортировать список с помощью лямбда-функции:

from sortedcontainers import SortedListWithKey

SortedListWithKey([[4, 'last'], [1, 'first']], key=lambda x: x[0])
# Result: SortedListWithKey([[1, 'first'], [4, 'last']], key=<function <lambda> at 0x107f5d730>)

Но допустим, мне нужно использовать set () , чтобы иметь только уникальные значения, документация говорит, что она также принимает key= param для сортировки пользовательской функцией, но я не могу заставить ее работать:

from sortedcontainers import SortedSet

SortedSet([[4, 'last'], [1, 'first']], key=lambda x: x[0])

Выдаст следующее исключение:

values = set(chain(*iterables))
TypeError: unhashable type: 'list'
Есть ли способ достичь этого?
1 2

1 ответ:

Упорядоченный набор элементов требует быть hashable. Ваши элементы-это списки, которые не поддерживают хэширование. Измените элементы на кортежи, и это будет работать:

>>> from sortedcontainers import SortedSet
>>> ss = SortedSet([(4, 'last'), (1, 'first')], key=lambda value: value[0])
>>> ss
SortedSet([(1, 'first'), (4, 'last')], key=<function <lambda> at 0x10fff4848>)

Это упорядоченное множество упорядочит элементы по первому индексу в паре. Преимущество кортежей в том, что они хэшируются, недостаток-в том, что они неизменны.

Рассмотрите возможность использования sortedcontainers.SortedDict вместо:

>>> sd = SortedDict({4: 'last', 1: 'first'})
>>> sd
SortedDict({1: 'first', 4: 'last'})
>>> sd[2] = 'second'
>>> sd.pop(4)
'last'

Сортированный дикт сохранит ключи в отсортированном порядке и позволит вам обновить значения до все, что угодно.