Created
May 30, 2020 07:19
-
-
Save jcmgray/866290fc3c76ba39211dc0ef72ffd900 to your computer and use it in GitHub Desktop.
oset - an fast ordered set implemenation using the 'orderedness' of py3.6+ dicts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class oset: | |
"""An ordered set which stores elements as the keys of a dict (ordered as | |
of python 3.6). 'A few times' slower than using a set directly for small | |
sizes, but makes everything deterministic. | |
""" | |
def __init__(self, it): | |
self._d = dict.fromkeys(it) | |
@classmethod | |
def _from_dict(cls, d): | |
obj = object.__new__(oset) | |
obj._d = d | |
return obj | |
@classmethod | |
def from_dict(cls, d): | |
"""Public method makes sure to copy incoming dictionary. | |
""" | |
return oset._from_dict(d.copy()) | |
def copy(self): | |
return oset.from_dict(self._d) | |
def add(self, k): | |
self._d[k] = None | |
def discard(self, k): | |
self._d.pop(k, None) | |
def remove(self, k): | |
self._d.pop(k) | |
def clear(self): | |
self._d.clear() | |
def update(self, *others): | |
for o in others: | |
self._d.update(o._d) | |
def union(self, *others): | |
u = self.copy() | |
u.update(*others) | |
return u | |
def intersection_update(self, *others): | |
if len(others) > 1: | |
si = set.intersection(*(set(o._d) for o in others)) | |
else: | |
si = others[0]._d | |
self._d = {k: None for k in self._d if k in si} | |
def intersection(self, *others): | |
if len(others) > 1: | |
si = set.intersection(*(set(o._d) for o in others)) | |
else: | |
si = others[0]._d | |
return oset._from_dict({k: None for k in self._d if k in si}) | |
def difference_update(self, *others): | |
if len(others) > 1: | |
su = set.union(*(set(o._d) for o in others)) | |
else: | |
su = others[0]._d | |
self._d = {k: None for k in self._d if k not in su} | |
def difference(self, *others): | |
if len(others) > 1: | |
su = set.union(*(set(o._d) for o in others)) | |
else: | |
su = others[0]._d | |
return oset._from_dict({k: None for k in self._d if k not in su}) | |
def __or__(self, other): | |
return self.union(other) | |
def __ior__(self, other): | |
self.update(other) | |
return self | |
def __and__(self, other): | |
return self.intersection(other) | |
def __iand__(self, other): | |
self.intersection_update(other) | |
return self | |
def __sub__(self, other): | |
return self.difference(other) | |
def __isub__(self, other): | |
self.difference_update(other) | |
return self | |
def __len__(self): | |
return self._d.__len__() | |
def __iter__(self): | |
return self._d.__iter__() | |
def __contains__(self, x): | |
return self._d.__contains__(x) | |
def __repr__(self): | |
return f"oset({list(self._d)})" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment