| 5 | |
| 6 | |
| 7 | class bidict(dict): |
| 8 | def __init__(self, *args, **kwargs): |
| 9 | super(bidict, self).__init__(*args, **kwargs) |
| 10 | self.inverse = {} |
| 11 | for key, value in self.items(): |
| 12 | self.inverse.setdefault(value, []).append(key) |
| 13 | |
| 14 | def __setitem__(self, key, value): |
| 15 | if key in self: |
| 16 | self.inverse[self[key]].remove(key) |
| 17 | super(bidict, self).__setitem__(key, value) |
| 18 | self.inverse.setdefault(value, []).append(key) |
| 19 | |
| 20 | def __delitem__(self, key): |
| 21 | self.inverse.setdefault(self[key], []).remove(key) |
| 22 | if self[key] in self.inverse and not self.inverse[self[key]]: |
| 23 | del self.inverse[self[key]] |
| 24 | super(bidict, self).__delitem__(key) |
| 25 | |
| 26 | def __getstate__(self): |
| 27 | return (self.inverse, dict(self)) |
| 28 | |
| 29 | def __setstate__(self, state): |
| 30 | self.inverse, data = state |
| 31 | self.update(data) |
| 32 | |
| 33 | def __reduce__(self): |
| 34 | return (bidict, (), self.__getstate__()) |