Skip to content

Instantly share code, notes, and snippets.

@pgp
Last active November 4, 2021 14:52
Show Gist options
  • Save pgp/d89dbfd057f78d1ce022f225cf6c9d0c to your computer and use it in GitHub Desktop.
Save pgp/d89dbfd057f78d1ce022f225cf6c9d0c to your computer and use it in GitHub Desktop.
# Generalization of dict, representing a multijection of m key sets K = k1,...,kn ; J = j1,...,jn ; ... ; Z = z1,...,zn
# storage complexity is O(m*n)
# set_view_index chooses the current key set to be used, all the remaining key sets are treated as value sets (the "total" value is returned as list)
# semantically equivalent to a SQL database table, in which every single column can be considered as a primary key one
# Assumption: every single column must not contain duplicate values within itself
# (BUT, an item can appear in different columns, even in the same position)
class Multijection(dict):
# each one of args is a list of items, each one that can be used as key
def __init__(self, *args):
super().__init__()
assert len(set(len(arg) for arg in args)) == 1 # each list must have the same size
self.lists = args
self.d = {} # backing dict for current view
self.set_view_index(0)
def set_view_index(self, idx):
if idx >= len(self.lists):
raise IndexError('Out of bounds')
keys = self.lists[idx]
values = []
for i in range(len(self.lists[0])):
values.append([x[i] for j,x in enumerate(self.lists) if j != idx])
self.d = dict(zip(keys,values))
def items(self):
return self.d.items()
def clear(self):
raise NotImplementedError
def popitem(self):
raise NotImplementedError
def keys(self):
return self.d.keys()
def values(self):
return self.d.values()
def get(self, key):
return self.d.get(key)
def __iter__(self):
return self.d.__iter__()
def __str__(self):
return self.d.__str__()
def __contains__(self, o):
return self.d.__contains__(o)
def contains_any(self, o):
return any(x.__contains__(o) for x in self.lists)
def __len__(self):
return self.d.__len__()
def __delitem__(self, v):
raise NotImplementedError
def __getitem__(self, k):
return self.d.__getitem__(k)
if __name__ == '__main__':
d = Multijection(['a', 'b', 'c'], [3.0, 2, 1.16], ['name1', 'name2', 'name3'])
# d.set_view_index(0) # already called during __init__
print(d['a']) # [3.0, 'name1']
d.set_view_index(1)
print(d[1.16]) # ['c', 'name3']
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment