Dictionary data types question

Beni Cherniavsky cben at techunix.technion.ac.il
Mon Mar 3 04:29:59 EST 2003


On 2003-03-01, Alonde wrote:

> dict={"one":1}
> How when I entered 1 and it return "one"?
>
If you want bi-directional mapping, the most effecient way is to keep
two dictionaries syncronized.  The hard part is defining what do you
want to happen when add the relation 'one' <-> 2 when you currently
have 'one' <-> 1 and 'two' <-> 2.  Suppose you want any conflict to be
an error, (in this example, the 2 existing relations should be deleted
before the new one can be added).  Then you can do (completely
untested):

class SyncedDict(dict):
    "Public attribute: `reverse` is the reverse `SyncedDict`."
    def __init__(self, reverse=None):
        if not reverse:
             reverse = SyncedDict(reverse=self)
        self.reverse = reverse
    def __setitem__(self, key, val):
        if (self.get(key, val) != val) or
            self.reverse.get(val, key) != key):
            raise KeyError
        super(SyncedDict, self)[key] = val
        super(SyncedDict, self.reverse)[val] = key
    def __delitem__(self, key):
        del super(SyncedDict, self)[key]
        del super(SyncedDict, self.reverse)[val]

Imaginary interaction:

>>> s = SyncedDict({'one': 1, 'two': 2})
>>> s
{'one': 1, 'two': 2}
>>> s.reverse
{1: 'one', 2: 'two'}
>>> s.reverse.reverse is s
True
>>> s['three'] = 3
>>> s.reverse[3]
'three'
>>> del s['three']
>>> s.reverse[3] = 33
>>> s
{1: 'one', 2: 'two', 33: 3}

If you don't need updating (the dictionary is computed once), this
should suffice instead:

>>> d1 = {'one': 1, 'two': 2}
>>> d2 = dict([(v, k) for k, v in d1.iteritems()])
>>> d2
{1: 'one', 2: 'two'}


An alternative model is a graph, where every item on each side can
correspond to more than one item on the other side.  This can be
modeled as a pair of dictionaries mapping from items to sets of
corresponding items.  This can be wrapped in a class similar to the
above (left as an excercise to the reader)...

In both models, if the keys/values are always from two distinct sets,
you can use the same dictionary for both mappings, e.g. d[1] == 'one'
and d['one'] == 1...

sitting-in-a-computer-farm-writing-Python-from-head-
because-my-home-harddisk-crashed-ly y'rs
  Beni Cherniavsky <cben at tx.technion.ac.il>






More information about the Python-list mailing list