[Tutor] TypeError: dict objects are unhashable

Tim Golden tim.golden at viacom-outdoor.co.uk
Fri Mar 24 17:35:33 CET 2006


[Ben Vinger]

| I want to create a dictionary (from SQL usernames) of
| the format:
|       accounts = {
|       ('psmit', '123456'): 'psmit',
|       ('rmatt', 'mypass'): 'rmatt',
|       }

Although possible, this structure looks a little
topsy-turvy: you're keying the dictionary on the
username & password, and the resultant value is the
username? I suspect you want to end up the other
way round?

| So I have:
|       accounts = {}
|       UserCursor.execute(sqlstr)
|       rows = UserCursor.fetchall()
|       UserConn.commit()

This commit looks unnecessary, unless you
have a truly strange SQL engine. You're
only selecting.. at least I assume you are
since you haven't provided the sqlstr.

|       for row in rows:
|             U = row['User']
|             P = row['Password']
|             InnerDict = {}
|             InnerDict[U] = P
|             accounts[InnerDict] = U
| 
| But I get:
| TypeError: dict objects are unhashable
| Unfortunately, I just can't see what I'm doing wrong

First things first: hashing refers to one of many techniques
of generating a unique number from some other object. Python
uses this number as a sort of sparse index for its dictionary
structure. 

Now for the lookup to be meaningful, an object must always hash
to the same value, otherwise you won't find it the next time round.
Certain Python objects are known as mutable -- their contents can
change -- and these objects obviously won't have a constant hash
value. A dictionary is one of these (a list is another) and that's
why you can't use them as keys in a dictionary.

OK, now we've got all that out of the way, I'm not entirely
sure why you're even trying to do that. To achieve the
structure you outlined above, you code wants to do something
like this:

U = row['User']
P = row['Password']
accounts[(U, P)] = U

where (U, P) is a *tuple*, not a dictionary which holds U and P
together in one structure. As I mentioned above, I rather suspect
you want something like:

accounts[U] = (U, P)

or even

accounts[U] = row

because it won't cost you anything to hang on to the whole
row, and it might be useful. But obviously you know best what
your own application needs.

Hope that helps
TJG

________________________________________________________________________
This e-mail has been scanned for all viruses by Star. The
service is powered by MessageLabs. For more information on a proactive
anti-virus service working around the clock, around the globe, visit:
http://www.star.net.uk
________________________________________________________________________


More information about the Tutor mailing list