Re: Possibly dumb question about dicts and __hash__()

2006-05-04 Thread Joel Hedlund
Hi!

 > Just the hash is not enough. You need to define equality, too:

Thanks a million for clearing that up.

Cheers!
/Joel
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Possibly dumb question about dicts and __hash__()

2006-05-03 Thread Peter Otten
Joel Hedlund wrote:

> 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__()

Just the hash is not enough. You need to define equality, too:

>>> class Named(object):
... def __init__(self, name):
... self.name = name
... def __hash__(self):
... return hash(self.name)
... def __eq__(self, other):
... try:
... other_name = other.name
... except AttributeError:
... return self.name == other
... return self.name == other_name
... def __repr__(self):
... return "Named(name=%r)" % self.name
...
>>> items = [Named(n) for n in "alpha beta gamma".split()]
>>> d = dict(zip(items, items))
>>> d["alpha"]
Named(name='alpha')

Peter

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Possibly dumb question about dicts and __hash__()

2006-05-03 Thread Joel Hedlund
Beautiful!

But how come my attempt didn't work? I've seen docs that explain how __hash__() 
methods are used to put objects in dict buckets:

http://docs.python.org/ref/customization.html#l2h-195

But if it's really hash(str(o)) that's used for dict keys, what good are 
__hash__() methods? Or am I reading the docs wrong?

/Joel
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Possibly dumb question about dicts and __hash__()

2006-05-03 Thread johnzenger
Actually, come to think of it, __str__ works just as well.

>>> class NamedThing(object):
 def __init__(self, name):
 self.name = name
 def __str__(self):
 return self.name
>>> d = {}
>>> d[a] = 1
>>> d[b] = 50
>>> d
{<__main__.NamedThing object at 0x00C528D0>: 1, <__main__.NamedThing
object at 0x00C529B0>: 50}
>>> d[a]
1
>>> d[b]
50

This is what you should use, instead of my first answer.  From the docs
for __repr__: "If at all possible, this should look like a valid Python
expression that could be used to recreate an object with the same value
(given an appropriate environment). If this is not possible, a string
of the form "<...some useful description...>" should be returned. ...
This is typically used for debugging, so it is important that the
representation is information-rich and unambiguous."



[EMAIL PROTECTED] wrote:
> 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 ''
> > 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': , : }
> >
> > If I wrap all keys in hash() calls I'm fine:
> > {2038943316: }
> >
> > 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

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Possibly dumb question about dicts and __hash__()

2006-05-03 Thread Bruno Desthuilliers
Joel Hedlund a écrit :
(snip)
 > How illegal is it? If I document it and put it in an opensource project,
 > will people throw tomatoes?

Don't know, but they'll sure do if you insist on top-posting !-)
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Possibly dumb question about dicts and __hash__()

2006-05-03 Thread Joel Hedlund
Hi!

Thanks for the quick response!

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

How illegal is it? If I document it and put it in an opensource project, will 
people throw tomatoes?

/Joel

[EMAIL PROTECTED] wrote:
> 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 ''
>>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': , : }
>>
>>If I wrap all keys in hash() calls I'm fine:
>>{2038943316: }
>>
>>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
> 
> 
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Possibly dumb question about dicts and __hash__()

2006-05-03 Thread johnzenger
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 ''
> 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': , : }
>
> If I wrap all keys in hash() calls I'm fine:
> {2038943316: }
>
> 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

-- 
http://mail.python.org/mailman/listinfo/python-list


Possibly dumb question about dicts and __hash__()

2006-05-03 Thread Joel Hedlund
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 ''
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': , : }

If I wrap all keys in hash() calls I'm fine:
{2038943316: }

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
-- 
http://mail.python.org/mailman/listinfo/python-list