473,668 Members | 2,449 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Possibly dumb question about dicts and __hash__()

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.__has h__()

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(obje ct):
def __init__(self, name):
self.name = name
def __hash__(self):
return self.name.__has h__()
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
May 3 '06 #1
7 1113
Use __repr__. Behold:
class NamedThing(obje ct): def __init__(self, name):
self.name = name
def __repr__(self):
return self.name
a = NamedThing("Del aware")
b = NamedThing("Haw aii")
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.__has h__()

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(obje ct):
def __init__(self, name):
self.name = name
def __hash__(self):
return self.name.__has h__()
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


May 3 '06 #2
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

jo********@gmai l.com wrote: Use __repr__. Behold:

class NamedThing(obje ct):
def __init__(self, name):
self.name = name
def __repr__(self):
return self.name

a = NamedThing("Del aware")
b = NamedThing("Haw aii")
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.__has h__()

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(obje ct):
def __init__(self, name):
self.name = name
def __hash__(self):
return self.name.__has h__()
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


May 3 '06 #3
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 !-)
May 3 '06 #4
Actually, come to think of it, __str__ works just as well.
class NamedThing(obje ct): def __init__(self, name):
self.name = name
def __str__(self):
return self.name d = {}
d[a] = 1
d[b] = 50
d {<__main__.Name dThing object at 0x00C528D0>: 1, <__main__.Named Thing
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."

jo********@gmai l.com wrote:
Use __repr__. Behold:
class NamedThing(obje ct): def __init__(self, name):
self.name = name
def __repr__(self):
return self.name
a = NamedThing("Del aware")
b = NamedThing("Haw aii")
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.__has h__()

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(obje ct):
def __init__(self, name):
self.name = name
def __hash__(self):
return self.name.__has h__()
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


May 3 '06 #5
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
May 3 '06 #6
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.nam e.__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='alp ha')

Peter

May 4 '06 #7
Hi!
Just the hash is not enough. You need to define equality, too:


Thanks a million for clearing that up.

Cheers!
/Joel
May 4 '06 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
1849
by: Thomas Guettler | last post by:
Hi! Can someone point me to the documentation of tuples __hash__ method? I want to unique a list of tuples. Since __hash__ returns a 32 bit integer, there could be a situtation where two different tupples return the same value.
39
3156
by: Marco Aschwanden | last post by:
Hi I don't have to talk about the beauty of Python and its clear and readable syntax... but there are a few things that striked me while learning Python. I have collected those thoughts. I am sure there are many discussions on the "problems" mentioned here. But I had this thoughts without looking into any forums or anything... it is kind of feedback.
3
2824
by: fdsl ysnh | last post by:
--- python-list-request@python.orgдµÀ: > Send Python-list mailing list submissions to > python-list@python.org > > To subscribe or unsubscribe via the World Wide Web, > visit > http://mail.python.org/mailman/listinfo/python-list > or, via email, send a message with subject or body > 'help' to
1
2270
by: Erik Max Francis | last post by:
I've come across a limitation in unpickling certain types of complex data structures which involve instances that override __hash__, and was wondering if it was known (basic searches didn't seem to come up with anything similar) and if there is a workaround for it short of restructuring the data structures in question. The fundamental issue rests with defining classes which override __cmp__ and __hash__ in order to be used as keys in...
65
4195
by: Steven Watanabe | last post by:
I know that the standard idioms for clearing a list are: (1) mylist = (2) del mylist I guess I'm not in the "slicing frame of mind", as someone put it, but can someone explain what the difference is between these and: (3) mylist =
3
2165
by: redefined.horizons | last post by:
I've been reading about Python Classes, and I'm a little confused about how Python stores the state of an object. I was hoping for some help. I realize that you can't create an empty place holder for a member variable of a Python object. It has to be given a value when defined, or set within a method. But what is the difference between an Attribute of a Class, a Descriptor in a Class, and a Property in a Class?
1
1260
by: gabor | last post by:
hi, if you have a new-style class, it will have a __hash__ method, even if you don't define it, because it inherits from object(). and, if you implement __eq__, then that default-hash-value will be probably wrong.
12
1810
by: Bill Jackson | last post by:
I have a dictionary of dictionaries where the keys are typically very long tuples and repeated in each inner dictionary. The dictionary representation is nice because it handles sparseness well...and it is nice to be able to look up values based on a string rather than a number. However, since my keys are quite long, I worry that I am wasting a lot of memory. I'm looking for better data structures. Here is an example: .... ...
12
1862
by: Alan Isaac | last post by:
This discussion ended abruptly, and I'd like to see it reach a conclusion. I will attempt to synthesize Bill and Carsten's proposals. There are two proposed patches. The first is to http://docs.python.org/lib/typesmapping.html where it is proposed for footnote (3) to state: Keys and values are listed in an arbitrary order. This order is indeterminate and generally depends on factors outside the scope
0
8459
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8371
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
8889
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8790
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8572
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8652
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
6206
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
1
2782
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
1779
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.