views:

275

answers:

4

I'm wondering if there is a built-in way to do this... Take this simple code for example:

D = {'one': objectA(), 'two': objectB(), 'three': objectC()}
object_a = D['one']

I believe object_a is just pointing at the objectA() created on the first line, and knows nothing about the dictionary D, but my question is, does Python store the Key of the dictionary value? Is there a way to get the Key 'one' if all you have is the variable object_a (without looping over the dictionary, of course)?

If not, I can store the value 'one' inside objectA(), but I'm just curious if Python already stores that info.

+6  A: 

I think no.

Consider the case of adding a single object to a (large) number of different dictionaries. It would become quite expensive for Python to track that for you, it would cost a lot for a feature not used by most.

unwind
+2  A: 

The dict mapping is not trivially "reversible" as you describe.

  1. The key must be immutable. It must be immutable so that it can be hashed for lookup and not suffer spontaneous changes.

  2. The value does not have to be immutable, it is not hashed for quick lookup.

You cannot simply go from value back to key without (1) creating an immutable value and (2) populating some other kind of mapping with the "reversed" value -> key mapping.

S.Lott
+2  A: 

Is there a way to get the Key 'one' if all you have is the variable object_a (without looping over the dictionary, of course)?

No, Python imposes no such near-useless redundancy on you. If objA is a factory callable:

d = {'zap': objA()}
a = d['zap']

and

b = objA()

just as well as

L = [objA()]
c = L[0]

all result in exactly the same kind of references in a, b and c, to exactly equivalent objects (if that's what objA gives you in the first place), without one bit wasted (neither in said objects nor in any redundant and totally hypothetical auxiliary structure) to record "this is/was a value in list L and/or dict d at these index/key" ((or indices/keys since of cource there could be many)).

Alex Martelli
A: 

Like others have said, there is no built-in way to do this, since it takes up memory and is not usually needed.

If not, I can store the value 'one' inside objectA(), but I'm just curious if Python already stores that info.

Just wanted to add that it should be pretty easy to add a more general solution which does this automatically. For example:

def MakeDictReversible(dict):
 for k, v in dict.iteritems():
  v.dict_key = k

This function just embeds every object in the dictionary with a member "dict_key", which is the dictionary key used to store the object.

Of course, this code can only work once (i.e., run this on two different dictionaries which share an object, and the object's "dict_key" member will be overwritten by the second dictionary).

Edan Maor