Python OrderedSet with .index() method

前端 未结 1 1762
栀梦
栀梦 2021-01-06 14:48

Does anyone know about a fast OrderedSet implementation for python that:

  • remembers insertion order
  • has an index() method (like the one lists offer)
1条回答
  •  小鲜肉
    小鲜肉 (楼主)
    2021-01-06 15:15

    You can always add it in a subclass. Here is a basic implementation for the OrderedSet you linked in a comment:

    class IndexOrderedSet(OrderedSet):
        def index(self, elem):
            if key in self.map:
                return next(i for i, e in enumerate(self) if e == elem)
            else:
                raise KeyError("That element isn't in the set")
    

    You mentioned you only need add, index, and in-order iteration. You can get this by using an OrderedDict as storage. As a bonus, you can subclass the collections.Set abstract class to get the other set operations frozensets support:

    from itertools import count, izip
    from collections import OrderedDict, Set
    
    class IndexOrderedSet(Set):
        """An OrderedFrozenSet-like object
           Allows constant time 'index'ing
           But doesn't allow you to remove elements"""
        def __init__(self, iterable = ()):
            self.num = count()
            self.dict = OrderedDict(izip(iterable, self.num))
        def add(self, elem):
            if elem not in self:
                self.dict[elem] = next(self.num)
        def index(self, elem):
            return self.dict[elem]
        def __contains__(self, elem):
            return elem in self.dict
        def __len__(self):
            return len(self.dict)
        def __iter__(self):
            return iter(self.dict)
        def __repr__(self):
            return 'IndexOrderedSet({})'.format(self.dict.keys())
    

    You can't subclass collections.MutableSet because you can't support removing elements from the set and keep the indexes correct.

    0 讨论(0)
提交回复
热议问题