Multikey Dict?

Mike Meyer mwm at mired.org
Sat Nov 12 19:57:51 EST 2005


David Rasmussen <david.rasmussen at gmx.net> writes:

> If I have a collection of dicts like:
> john = {'id': 1, 'name': "John Cleese", 'year': 1939}
> graham = {'id': 2, 'name': "Graham Chapman", 'year': 1941}
> I could store all of them in a list. But for easy lookup, I might
> store all these in a dict instead, like
> people = {'1': john, '2': graham}
> or maybe
> people = {'John Cleese': john, 'Graham Chapman': graham}
>
> or whatever key I might choose. Now, first of all, it seems a bit
> annoying that I have to keep that redundant data in the second dict
> that is already in the individual dicts within people.

I don't see any redundant data in the dictionary. The *keys* might be
redundant, but that's because of the way you chose to store them.

> Secondly (and this is my question), it is annoying that I have to
> choose one of several unambiguous keys as a key.

So use them all. No big deal.

> I would like to be able to say:
> people['1'].year
> in some case and in other cases I want to say
> people['John Cleese'].year

This syntax looks like the values of the dictionary are objects, and
you're referencing attributes as opposed to looking up values in a
dictonary.

> Also, I would like if I didn't have to keep the key data both in the
> dict of dicts and in the dicts :)

Then don't. Dictionary keys are references objects. Make sure you
reference use the same object in both dictionaries.

> If I could just say to Python: john and graham (and ...) are all a
> part of a "superdict" and either their id or their name can be used as
> keys.
>
> Can I do that somehow?

It's easy enough to build your superdict class:

# Untested code
class SuperDict(dict):
      def __init__(self, *keys):
          dict.__init__(self)
          self.keys = *keys

      def __setitem__(self, key, item):
      	  # Set the explicit key
          dict.__setitem__(self, key, item)

          # Set the implicit keys
          for k in self.keys:
              dict.__setitem__(self, item[k], item)

I think that gives you the behavior you want, except you have to use
the index syntax for both indices, instead of beinng able to use the
attribute syntax for the object returned by the dictionary.

          <mike
-- 
Mike Meyer <mwm at mired.org>			http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.



More information about the Python-list mailing list