[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