Here is a quick implementation:
class MultipleKeyDict(dict): __slots__ = ["_primary_keys"] def __init__(self, arg=None, **kwargs): self._primary_keys = {} self.update(arg, **kwargs) def __setitem__(self, key, value): super(MultipleKeyDict, self).__setitem__(key, value) self._primary_keys.setdefault(value, key) def __delitem__(self, key): value = self[key] super(MultipleKeyDict, self).__delitem__(key) if self._primary_keys[value] == key: del self._primary_keys[value] for k, v in super(MultipleKeyDict, self).iteritems(): if v == value: self._primary_keys[value] = k break def __iter__(self): return self.iterkeys() def update(self, arg=None, **kwargs): if arg is not None: if isinstance(arg, collections.Mapping): for k in arg: self[k] = arg[k] else: for k, v in arg: self[k] = v for k in kwargs: self[k] = kwargs[k] def clear(self): super(MultipleKeyDict, self).clear() self._primary_keys.clear() def iteritems(self): for v, k in self._primary_keys.iteritems(): yield k, v def items(self): return list(self.iteritems()) def itervalues(self): return self._primary_keys.iterkeys() def values(self): return self._primary_keys.keys() def iterkeys(self): return self._primary_keys.itervalues() def keys(self): return self._primary_keys.values()
The only messy bit is that it should look for the entire dict if the primary key is deleted.
I missed copy()
, pop()
, popitem()
and setdefault()
. If you need them, you will have to implement them yourself.
source share