repr(x) == repr(y) <=> x == y AND eval(repr(x)) == x

Christopher A. Craig list-python at ccraig.org
Sat Oct 19 12:50:59 EDT 2002


Chad Netzer <cnetzer at mail.arc.nasa.gov> writes:

> On Friday 18 October 2002 12:56, Chad Netzer wrote:
> 
> > Furthermore, a straightforward trick is to wrap your object in a single
> > element tuple, and use that as the key.  It is a much *MUCH* better
> > solution than monkeying with 'eval( repr( x ) )'.
> 
>    Well, upon further investigation, it appears this trick's main fault is 
> that it is bollocks.  It won't work:
> 
> a = {}
> b = {}
> a[ (b,) ] = 1
> 
> I thought the above would work, but it seems not to.  Anyone care to explain 
> why (I'm off to look in the reference manual, in the meantime.)

I don't think it's there explicitly, but it is sort of hinted at.
First off, the spec does not require all immutable objects to be
hashable (and tuples containing mutable objects are an examle of some
that aren't). But this passage is more important:

  "The only required property [for hashing] is that objects which
   compare equal have the same hash value; it is advised to somehow
   mix together (e.g., using exclusive or) the hash values for the
   components of the object that also play a part in comparison of
   objects."

Tuple hash is defined (in tupleobject.c) as

def hash(t):
  x = 0x345678
  for ob in t:
    y = hash(ob)  # note this line in particular
    if y==-1: return -1
    x = (1000003*x) ^ y
  x ^= len(t)
  if (x == -1): return -2
  return x

which is, of course, recursive on the elements of the tuple.  As such,
tuples containing mutable objects are not hashable. 

-- 
Christopher A. Craig <list-python at ccraig.org>
"Tragedy is when I cut my finger.  Comedy is when you fall in an open
sewer and die."  Mel Brooks.




More information about the Python-list mailing list