Can dictionary values access their keys?

Steve Holden steve at holdenweb.com
Fri Apr 8 12:45:17 EDT 2005


Matthew Thorley wrote:
> This may be a very rudimentary question, but here goes:
> 
> If I have a simple dictionary, where the value is a class or function,
> is there an interface through which it can discover what its key is?
> Similar to index() for list.
> 
No, because mapping types (of which dict is the canonical example) don;t 
guarantee uniqueness of values. In other words, there can be several 
keys mapping to the same value.

You would therefore need to know how to handle such cases - would you 
want to return an arbitrary one of those keys, or a list of them all?

A standard dict doesn't keep any record of the order in which keys were 
added, so there are some things you *can't* do, like return "the first 
key added with a given value".

> For a list, assuming I new what the parent list was I could do something
> like this.
> 
> 
>>>>class child:
> 
> ...     def get_parent_index(self, parent):
> ...             return parent.index(self)
> ...
> 
>>>>a = child()
>>>>l = [a]
>>>>b = l[0]
>>>>b.get_parent_index(a)
>>>>b.get_parent_index(l)
> 
> 0
> 
> Is there a way to do something like that with dicts?
> 
So you know about the .index() and .find() methods, and of course since 
there is no guarantee that a value appears only once in the list they 
disambiguate by returning the lowest index containing the value.

A simple way to do what you appear to want would be:

     def get_parent_index(self, parent):
         for k, v in parent.items():
             if v == self:
                 return k

This would return None if the required item wasn't found in the dict parent.
> 
> On a similar note, if one object is part of another, is there a way for
> the 'child' obj to discover what/who the 'parent' object is? That way
> parent does not have to be explicityly passed to get_parent_index?
> 
This is like asking if you can find the "name" of an object. The fact is 
that a single object can be bound to many variables. Suppose I write:

     lst = [1, 2, 3]

does that mean that the "name" of 2 is lst[1]? No - 2 is just a value 
that happens to be bound to that list element (among other things).

If I then write

     otherlst = lst
     otherlst[1' = "two"

you will find that lst[1] is also now bound to "two" because lst and 
otherlst are in fact references tot he same list object, so changing one 
also changes the other. Given that, what is the "name" of that list?

> The idea is like this:
> 
> 
>>>>class child:
> 
> ...     def get_parent_index(self):
> 		parent = self.magic_parent_discovery()
> ...             return parent.index(self)
> ...
> 

Given a set of objects and a known attribute or set of attributes for 
those objects that might be references to a specific search target you 
can perform the magic you want, but a generic search for "any reference 
to the search target", while not impossible (using Python's excellent 
introspection facilities) is way beyond what most people would consider 
practical. Obviously the garbage collector has to solve this problem, 
but you *really* don't want to be doing this stuff in Python unless you 
absolutely *must*.

regards
  Steve
-- 
Steve Holden        +1 703 861 4237  +1 800 494 3119
Holden Web LLC             http://www.holdenweb.com/
Python Web Programming  http://pydish.holdenweb.com/




More information about the Python-list mailing list