-1

New python learner here and i encountered a problem where it says my dict is unhashable. I searched up this on stack overflow for other answers but i couldn't understand them well. Does any one have a explanation for what is unhashable that is easy to understand? Also here is the part of my code where things went wrong

for name1, itemdescription1 in thisitem.items():
    if rooms[currentroom-1][currentroom]["items"][name1][itemdescription1] == "yes": # if player already got this item
        print ("You didn't find anything")

on the middle line of the code above it says TypeError: unhashable type: 'dict' And here is my code for the

rooms = [

    {1 : {
        "name" : "hall",
        "east" : 2,
        "south" : 3,
        "description" : "An empty hallway, nothing of use here. ",
        "items" : {"torch" : {"a dim torch " : "no"}}
    }}, 
    {2 : {
        "name" : "kitchen",
        "west" : 1,
        "east" : 4,
        "south" : 6,
        "description" : "An odd smell reeks from the kitchen. What could it be? ",
        "items" : {"meat" : {"a piece of vile meat " : "no"}}
    }},
    {3 : {
        "name" : "bedroom",
        "north" : 1,
        "east" : 6,
        "description" : "A overwelmingly big room containing two gigantic beds, hmmm... ",
        "items" : {"key" : {"a silver key " : "no"}}
    }},
    {4 : {
        "name" : "diningroom",
        "west" : 2,
        "south" : 5,
        "description" : "A large room with tables and chairs, nothing special. ",
        "items" : {"plate" : {"a white plate " : "no"}}
    }},

    {5 : {
        "name" : "bathroom",
        "north" : 4,
        "west" : 6,
        "description" : "A creepy shadow lays in the bathtub, better go somewhere else. ",
        "items" : {"shampoo" : {"a bottle of shampoo " : "no"}}
    }},
    {6 : {
        "name" : "garage",
        "north" : 2,
        "west" : 3,
        "east" : 5,
        "description" : "It reeks of blood here. You wonder why. ",
        "items" : {"bolts" : {"some rusted iron bolts " : "no"}} 
}}
]
pythonsohard
  • 127
  • 9
  • What are the values in `thisitem.items()`? – AKS Apr 29 '16 at 04:22
  • 1
    Can you please create a [Minimum, Complete and Verifiable Example](http://stackoverflow.com/help/mcve) of your issue? Right now its difficult to say what the issue is, as all of the applicable code is not present. – Paul Rooney Apr 29 '16 at 04:26
  • 2
    Print `name1` and `itemdescription1`. Atleast one of them is of type `dict` and you are trying to use it as key in a dict, hence the error. – Muhammad Tahir Apr 29 '16 at 04:28
  • short question: in a dict like {a: b}, which one is the key? and what do you call the other one? thank you – pythonsohard Apr 30 '16 at 05:16

1 Answers1

3

Answer To the Question As Stated

Any object that does not implement the __hash__() and __eq()__ magic methods in its class definition is unhashable.

A hashable object is something that can be mapped to a unique identifying value - think of a function that can take your object and return a corresponding unique number, and you have the right idea. They are the buildings blocks of hashtables and dictionaries, which work on the premise that this unique value (the hash) of a key is meant to refer to the block of memory where the value is stored - that way you can look up the value of a key very, very quickly (constant time, in fact).

In practice, this unhashability condition usually means that mutable objects - objects whose contents can be changed in memory, rather than by returning a new modified object - are unhashable.

Lists and dictionaries are unhashable. Tuples, strings and integers - all immutable objects - are hashable.

It is possible to extend lists and dictionaries in such a way that they are hashable. However, there are only a few niche use cases that can justify the use of hashable dictionaries and lists. This is not, in my opinion, one of them.


Answer to the Actual Underlying Question

Unhashable type errors are usually thrown when you take a dictionary A and an unhashable object B and you try to use B as a key i.e. you call A[B].

Your error comes simply from the fact that one of name1, currentroom or itemdescription1 is a dictionary, and you tried to look up one of these in another dictionary.

Without the full code, we can't be certain which of these is the culprit, but you can rest assured that the error comes from there.

Community
  • 1
  • 1
Akshat Mahajan
  • 9,543
  • 4
  • 35
  • 44
  • Most probably it is `itemdescription1`. As if it would have been `currentroom`, OP would have got error "unsupported operands dict and int" (for currentroom -1). And `name1` itself is a key in a dict (`thisitem`) so `itemdescription1` should be the culprit. – Muhammad Tahir Apr 29 '16 at 05:21