[Tutor] How to get a key from dictionary?

Kirby Urner urnerk@qwest.net
Mon, 25 Mar 2002 17:26:29 -0800


At 05:23 PM 3/25/2002 -0600, Isaac Hall wrote:
>If that is the case, then the best way I have thought of
>so far is to place a list as the value for each new key.

Yes, I had to do something like this recently.  I wanted
a dictionary of spheres keyed by floating point distance
from the origin, but with several values possible at the
same distance (same key).  So I decided to just accumulate
all those sharing a key in a list.  Sometimes this is a
good solution.

>def addtodict(dict):           # Import a normal dictionary

Not really importing -- just passing a dictionary as a
parameter.

>     for key in dict.has_key(): # loop over all keys
>         if dict[dict[key]]:     #see if we already have an
>                                 #entry for each value
>             dict[dict[key]].append(key) #if so, append to it
>         else:
>             dict[dict[key]] = [key] #if not create it
>
>I haven't tested this, but something of this nature should work.

Very untested :-D.  dict.has_key returns 1 or 0 (true or
false) so isn't something to iterate over with for.

An easy way to accumulate:

  >>> def addtodict(thedict, thekey, thevalue):
         thedict[thekey] = thedict.get(thekey,[]) + [thevalue]


  >>> thedict = {}
  >>> addtodict(thedict,'aa',1)
  >>> addtodict(thedict,'bb',3)
  >>> addtodict(thedict,'aa',2)
  >>> addtodict(thedict,'cc',4)
  >>> addtodict(thedict,'bb','r')
  >>> thedict
  {'aa': [1, 2], 'cc': [4], 'bb': [3, 'r']}

What this does is use thedict.get(thekey,[]) + [thevalue]
to return return the existing value appended to the new
value, or, if there's no existing value, to initialize
with [thevalue] (because if there's no existing value,
thedict.get(thekey,[]) returns [] and [] + [thevalue]
is just [thevalue].

The above is sort of non-functional programming in that
it uses a function to change a dictionary object passed
as a parameter, but returns nothing.  You can return
thedict if you prefer syntax like:

   >>> thedict = add2dict(thedict, 'rr', 78)

You can also define the function with thedict assumed
global.  Or have a function factory to bind a specific
dictionary (extending a thread I was working on earlier):

  >>> def addto(thedict):
          def main(thekey,thevalue):
             thedict[thekey] = thedict.get(thekey,[]) + [thevalue]
          return main

  >>> it = {}             # some dictionary
  >>> add2it = addto(it)  # a function for this dict in particular
  >>> add2it
  <function main at 0x01256F20>
  >>> add2it('aa',1)       # no need to mention which dictionary
  >>> add2it('aa',2)
  >>> add2it('bb',3)
  >>> it
  {'aa': [1, 2], 'bb': [3]}

Kirby