[Python-ideas] Dict with inverse form
Andrew Barnert
abarnert at yahoo.com
Fri Feb 12 19:23:05 EST 2016
On Feb 12, 2016, at 15:59, Chris Barker <chris.barker at noaa.gov> wrote:
>
>> On Fri, Feb 12, 2016 at 3:02 PM, Nikolaus Rath <Nikolaus at rath.org> wrote:
>>
>> Are there use cases where the set of keys and the set of values is
>> overlapping?
>>
>> In most cases you can probably get away by not offering an "inverse"
>> object at all, just let regular lookup fall back on value lookup.
>
> hmm, interesting. my use case at hand is mapping color name strings to RGB values -- it should be a one to one relationship, and I need to look for either one.
>
> But you are quite right, they would never overlap, unless someone decided a nice name for a color would be "(125, 15, 235)" -- even then they wouldn't because the RGB value sare a tuple, not a string.
>
> So that may be the way to get the easiest interface.
If that's your use case, there's an even easier interface: just toss the forward and reverse mappings in the same dict. If you don't need to iterate the dict[^1] or print in user-friendly form, it's hard to beat that for simplicity or compactness.[^2]
Of the top of my head (untested):
class SelfInvertingDict(dict):
def __delitem__(self, key):
super().__delitem__(self[key])
super().__delitem__(key)
def __setitem__(self, key, value):
if value in self and self[value] != key:
raise ValueError("duplicate key: '{}'".format(value)
if key in self: del self[key]
super().__setitem__(key, value)
super().__setitem__(value, key)
[^1]: Even if you do need to iterate, you can always do "(or don't mind iterating with a type switch like "names = (key for key in d if isinstance(key, str))"
[^2]: On the other hand, it's pretty easy to beat for static-type-checking purposes. The actual type of that dual dict is pretty ugly, and probably not describable in mypy terms, so presumably you'd just punt and label it Dict[Any, Any], or at best stick Union types in for key and value. But that's true for the double-dict-with-fall-through design too.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20160212/2e78fe5c/attachment-0001.html>
More information about the Python-ideas
mailing list