Possibly dumb question about dicts and __hash__()

johnzenger at gmail.com johnzenger at gmail.com
Wed May 3 16:03:54 EDT 2006


Use __repr__.  Behold:

>>> class NamedThing(object):
     def __init__(self, name):
         self.name = name
     def __repr__(self):
         return self.name

>>> a = NamedThing("Delaware")
>>> b = NamedThing("Hawaii")
>>> d = {}
>>> d[a] = 1
>>> d[b] = 50
>>> print d
{Delaware: 1, Hawaii: 50}
>>> d[a]
1
>>> d[b]
50

Although this is a bit illegal, because repr is not supposed to be used
this way.

Joel Hedlund wrote:
> Hi!
>
> There's one thing about dictionaries and __hash__() methods that puzzle me. I
> have a class with several data members, one of which is 'name' (a str). I would
> like to store several of these objects in a dict for quick access
> ({name:object} style). Now, I was thinking that given a list of objects I might
> do something like
>
> d = {}
> for o in objects:
>      d[o] = o
>
> and still be able to retrieve the data like so:
>
> d[name]
>
> if I just defined a __hash__ method like so:
>
> def __hash__(self):
>      return self.name.__hash__()
>
> but this fails miserably. Feel free to laugh if you feel like it. I cooked up a
> little example with sample output below if you care to take the time.
>
> Code:
> ---------------------------------------------------------------
> class NamedThing(object):
>      def __init__(self, name):
>          self.name = name
>      def __hash__(self):
>          return self.name.__hash__()
>      def __repr__(self):
>          return '<foo>'
> name = 'moo'
> o = NamedThing(name)
> print "This output puzzles me:"
> d = {}
> d[o] = o
> d[name] = o
> print d
> print
> print "If I wrap all keys in hash() calls I'm fine:"
> d = {}
> d[hash(o)] = o
> d[hash(name)] = o
> print d
> print
> print "But how come the first method didn't work?"
> ---------------------------------------------------------------
>
> Output:
> ---------------------------------------------------------------
> This output puzzles me:
> {'moo': <foo>, <foo>: <foo>}
>
> If I wrap all keys in hash() calls I'm fine:
> {2038943316: <foo>}
>
> But how come the first method didn't work?
> ---------------------------------------------------------------
>
> I'd be grateful if anyone can shed a litte light on this, or point me to some
> docs I might have missed.
>
> Also:
> Am I in fact abusing the __hash__() method? If so - what's the intended use of
> the __hash__() method?
>
> Is there a better way of implementing this?
>
> I realise I could just write
>
> d[o.name] = o
>
> but this problem seems to pop up every now and then and I'm curious if there's
> some neat syntactic trick that I could legally apply here.
> 
> Thanks for your time!
> /Joel Hedlund




More information about the Python-list mailing list