Есть ли у Python упорядоченный набор?

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

В качестве примера Boost.Spirit очень удобно использует оператор запятой для реализации инициализаторов списка для таблиц символов. Таким образом, он делает следующий синтаксис возможным и значимым:

keywords = "and", "or", "not", "xor";

Обратите внимание, что из-за приоритета оператора код (намеренно!) Идентичен

(((keywords = "and"), "or"), "not"), "xor";

То есть, первый оператор называется keywords.operator =("and"), который возвращает прокси-объект, на который вызывается оставшийся operator, s:

keywords.operator =("and").operator ,("or").operator ,("not").operator ,("xor");

406
задан Jean-François Corbett 9 March 2017 в 15:01
поделиться

2 ответа

Существует рецепт упорядоченного набора (возможная новая ссылка ), на который имеется ссылка в Документации Python 2 . Это работает на Py2.6 или новее и 3.0 или новее без каких-либо изменений. Интерфейс почти такой же, как у обычного набора, за исключением того, что инициализация должна выполняться списком.

OrderedSet([1, 2, 3])

Это MutableSet, поэтому подпись для .union не соответствует сигнатуре set, но поскольку он включает __ или __ , можно легко добавить нечто подобное:

@staticmethod
def union(*sets):
    union = OrderedSet()
    union.union(*sets)
    return union

def union(self, *sets):
    for set in sets:
        self |= set
197
ответ дан 22 November 2019 в 23:20
поделиться

Упорядоченный набор функционально является частным случаем упорядоченного словаря.

Ключи словаря словарь уникален. Таким образом, если пренебречь значениями в упорядоченном словаре (например, присвоив им Нет ), то получится, по сути, упорядоченный набор.

Начиная с Python 3.1 существует collections.OrderedDict . Ниже приведен пример реализации OrderedSet. (Обратите внимание, что необходимо определить или переопределить только несколько методов: collections.OrderedDict и collections.MutableSet делают тяжелую работу.)

import collections

class OrderedSet(collections.OrderedDict, collections.MutableSet):

    def update(self, *args, **kwargs):
        if kwargs:
            raise TypeError("update() takes no keyword arguments")

        for s in args:
            for e in s:
                 self.add(e)

    def add(self, elem):
        self[elem] = None

    def discard(self, elem):
        self.pop(elem, None)

    def __le__(self, other):
        return all(e in other for e in self)

    def __lt__(self, other):
        return self <= other and self != other

    def __ge__(self, other):
        return all(e in self for e in other)

    def __gt__(self, other):
        return self >= other and self != other

    def __repr__(self):
        return 'OrderedSet([%s])' % (', '.join(map(repr, self.keys())))

    def __str__(self):
        return '{%s}' % (', '.join(map(repr, self.keys())))

    difference = property(lambda self: self.__sub__)
    difference_update = property(lambda self: self.__isub__)
    intersection = property(lambda self: self.__and__)
    intersection_update = property(lambda self: self.__iand__)
    issubset = property(lambda self: self.__le__)
    issuperset = property(lambda self: self.__ge__)
    symmetric_difference = property(lambda self: self.__xor__)
    symmetric_difference_update = property(lambda self: self.__ixor__)
    union = property(lambda self: self.__or__)
137
ответ дан 22 November 2019 в 23:20
поделиться
Другие вопросы по тегам:

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