Skip to content

Instantly share code, notes, and snippets.

@YabZhang
Created April 13, 2019 10:46
Show Gist options
  • Select an option

  • Save YabZhang/b2e43b43549c0d1682408f66c18ef3f3 to your computer and use it in GitHub Desktop.

Select an option

Save YabZhang/b2e43b43549c0d1682408f66c18ef3f3 to your computer and use it in GitHub Desktop.
ordersed set
#!/usr/bin/env python3
from collections import MutableSet
from weakref import proxy
class Node(object):
__slots__ = ["prev", "next", "key", "__weakref__"]
class OrderedSet(MutableSet):
def __init__(self, iterable=None):
root = self.__root = Node()
root.prev = root.next = root
self.__map = {}
if iterable is not None:
self |= iterable
def __len__(self):
return len(self.__map)
def __contains__(self, key):
return key in self.__map
def add(self, key):
if key not in self.__map:
self.__map[key] = node = Node()
root = self.__root
last = root.prev
node.prev, node.next, node.key = last, root, key
last.next = root.prev = proxy(node)
def discard(self, x):
if x in self.__map:
node = self.__map.pop(x)
node.prev.next = node.next
node.next.prev = node.prev
def __iter__(self):
root = self.__root
node = root.next
while node is not root:
yield node.key
node = node.next
def __reversed__(self):
root = self.__root
node = root.prev
while node is not root:
yield node.key
node = node.prev
def pop(self, last=False):
if not self.__map:
raise KeyError("set is empty")
key = next(reversed(self)) if last else next(iter(next))
return self.discard(key)
def __repr__(self):
cls_name = self.__class__.__name__
if not self:
return "%s()" % cls_name
return "%s(%r)" % (cls_name, list(self))
def __eq__(self, other):
if isinstance(other, list):
return len(other) == len(self) and list(other) == list(self)
return not (self ^ other)
if __name__ == "__main__":
# import pdb
# pdb.set_trace()
a = [1, 2, 3]
oset = OrderedSet(iterable=a)
print("ordered set:", oset)
oset.add(4)
print("ordered set:", oset)
print("pop: ", oset.pop(last=True))
print("ordered set:", oset)
bset = set(a)
print("set comp orderset:", bset == oset, bset, oset)
cset = OrderedSet(iterable=a)
print("orderedset comp orderset:", cset == oset, cset, oset)
a[0] = 0
cset = OrderedSet(iterable=a)
print("orderedset comp orderset:", cset == oset, cset, oset)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment