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