Search code examples
pythondictionarykeymultiple-value

How to make a dictionary, in which multiple values access one value(Python)


I want to make a Python dictionary. I want values like 0.25, 0.30, 0.35 to be keys in this dictionary. The problems is that I have values like 0.264, 0.313, 0.367. I want this values to access the keys e.g. I want every value from 0.25(inclusive) to 0.30(exclusive) to access the value under the key 0.25. Any ideas how to do this? I think I've done that before somehow, but I have no ideas right now. Thanks in advance.


Solution

  • Create a subclass of dict with adjusted __getitem__, __setitem__, __delitem__, __contains__, get(), pop() and update() methods that round the key:

    class RoundingDict(dict):
        def _round(self, key):
            return int(key * 20) / 20.0
    
        def __contains__(self, key):
            return super(RoundingDict, self).__contains__(self._round(key))
    
        def __getitem__(self, key):
            return super(RoundingDict, self).__getitem__(self._round(key))
    
        def __setitem__(self, key, value):
            super(RoundingDict, self).__setitem__(self._round(key), value)
    
        def __delitem__(self, key):
            super(RoundingDict, self).__delitem__(self._round(key))
    
        def get(self, key, default=None):
            return super(RoundingDict, self).get(self._round(key), default)
    
        def pop(self, key, default=None):
            return super(RoundingDict, self).pop(self._round(key), default)
    
        def update(self, iterable):
            try:
                super(RoundingDict, self).update({
                    self._round(k): v for k, v in iterable.iteritems()})
            except AttributeError:
                super(RoundingDict, self).update((
                    (self._round(k), v) for k, v in iterable))
    

    This floors any key down to the nearest 0.05 multiple when getting, setting or deleting individual keys, as well as when updating the dictionary with multiple keys:

    >>> d = RoundingDict()
    >>> d[0.346] = 'Foo'
    >>> d[0.34]
    'Foo'
    >>> d[0.30]
    'Foo'
    >>> d[0.35]
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "<string>", line 6, in __getitem__
    KeyError: 0.35
    >>> d.get(0.34)
    'Foo'
    >>> d.get(0.35, 'default')
    'default'