Here is an example of how you might create a class to do this for you. Be aware that this is quite slow when setting new / editing existing values.
class DoubleDict:
def __init__(self, *dicts, **extras):
self.dict1 = {}
for dct in dicts:
self.dict1 |= dct
self.dict1 |= extras
self.dict2 = dict(zip(self.dict1.values(), self.dict1.keys()))
def __getitem__(self, key):
try: return self.dict1.__getitem__(key)
except KeyError: return self.dict2.__getitem__(key)
def __setitem__(self, key, value):
if key in self.dict1:
self.dict2.pop(self.dict1[key])
self.dict1.pop(key)
elif key in self.dict2:
self.dict1.pop(self.dict2[key])
self.dict2.pop(key)
if value in self.dict1:
self.dict2.pop(self.dict1[value])
self.dict1.pop(value)
elif value in self.dict2:
self.dict1.pop(self.dict2[value])
self.dict2.pop(value)
self.dict1[key] = value
self.dict2[value] = key
def __iter__(self):
total_dict = self.dict1 | self.dict2
return total_dict.__iter__()
def __repr__(self):
return f"DoubleDict({repr(self.dict1)})"
def __str__(self):
return "\n".join(f"{key} <==> {self.dict1[key]}" for key in self.dict1)
Here is how it works:
a = DoubleDict({1: 2, 3: 4, 5: 6, 7: 8})
print(a)
# 1 <==> 2
# 3 <==> 4
# 5 <==> 6
# 7 <==> 8
a[1] = 3
# Now the 3,4 pair and the 1,2 pair no longer exist, but there is a new 3,1 pair
print(a[1], a[3])
# 3 1
print(a)
# 5 <==> 6
# 7 <==> 8
# 1 <==> 3