Last active
November 4, 2021 14:52
-
-
Save pgp/d89dbfd057f78d1ce022f225cf6c9d0c to your computer and use it in GitHub Desktop.
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
# 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