I'm wondering what is the closest to a "SetList"; a list with all the amazing properties of both a list and a set.
For example, I'd want to index/subset it like a list, but make use of contains
checking of a set, and making sure everything in it is unique.
Why not have both a set and a list occupying the same values (I know it is a terrible idea, there must be a way to contain the values once)? I figured it would be possible to implement all methods such that the list and set will always stay in sync.
I started with something like this:
class SetList():
def __init__(self, x = None):
if isinstance(x, list):
self.l = []
self.s = set()
for y in x:
if y not in self.s:
self.l.append(y)
self.s.add(y)
elif isinstance(x, set):
self.l = list(x)
self.s = x
elif isinstance(x, SetList):
self.l = SetList.l
self.s = SetList.s
elif x is None:
self.l = []
self.s = set()
else:
self.l = [x]
self.s = set(self.l)
def append(self, a):
if a not in self.s:
self.l.append(a)
self.s.add(a)
def add(self, a):
self.append(a)
def remove(self, r):
if r in self.s:
self.l.remove(r)
self.s.remove(r)
def pop(self, p = None):
if p is not None:
x = self.l.pop(p)
else:
x = self.l.pop()
self.s.remove(x)
return x
def __getitem__(self, i):
if isinstance(i, int):
return self.l[i]
else:
return SetList(self.l[i])
def __len__(self):
return len(self.s)
def __repr__(self):
return 'SetList({})'.format(self.l)
def __add__(self, container):
for x in container:
if x not in self.s:
self.add(x)
return self
def __iter__(self):
return self.l.__iter__()
def __item__(self, x):
return self.l.__item__(x)
def __and__(self, x):
return self.__add__(x)
def __eq__(self, x):
try:
return self.l == x.l
except AttributeError:
return False
Here to see the goodness in action:
sl = SetList()
for x in [1,2,3,4,1,2,3]:
sl.add(x)
>>> sl[1:2] + [1,3] != sl[1:2] & [3,1]
True
>>> sl[1:2] + [1,3] == sl[1:2] & [1,3]
True
Though I'm wondering if there are already such implementations out there?