Python has an ordered dictionary, what about an ordered set?
This question previously had a warning that there was going to be a self-answer.
Python has an ordered dictionary, what about an ordered set?
This question previously had a warning that there was going to be a self-answer.
There is an ordered set recipe for this which is referred to from the Python Documentation. This runs on Py2.6 or later and 3.0 or later without any modifications. The interface is exactly the same as a normal set, except that initialisation should be done with a list.
OrderedSet([1, 2, 3])
The keys of a dictionary are unique. Thus, if one disregards the values in an ordered dictionary (e.g. by assigning them None
), then one has essentially an ordered set.
As of Python 3.1 there is collections.OrderedDict
. The following is an example implementation of an OrderedSet. (Note that only few methods need to be defined or overridden: collections.OrderedDict
and collections.MutableSet
do the heavy lifting.)
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__)