andrewm4894
andrewm4894

Reputation: 1558

Python unhashable type dict question on why these two approaches have different outcomes

I stumbled accross this question and was wondering why i cannot do this:

# this does not work
pipeline = {
    {"resample" : {"type" : "trans", "name" : "resample", "kwargs" : {"rule" : "1min"}}}
}
pipeline

As it gives:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-10-7305ba79e664> in <module>
      1 pipeline = {
----> 2     {"resample" : {"type" : "trans", "name" : "resample", "kwargs" : {"rule" : "1min"}}}
      3 }
      4 pipeline
TypeError: unhashable type: 'dict'

But i can do this:

# this does work
pipeline = dict()
pipeline["resample"] = {"type" : "trans", "name" : "resample", "kwargs" : {"rule" : "1min"}}
pipeline

which gives:

{'resample': {'type': 'trans', 'name': 'resample', 'kwargs': {'rule': '1min'}}}

I was just curious more then anything as it feels like i'm doing same thing in terms of end result but just not sure why first approach fails but 2nd one is ok.

Upvotes: 1

Views: 250

Answers (3)

New2coding
New2coding

Reputation: 717

The construct of dictionary is supposed to be key:value pairs so in your case the "resample" is key and appropriate dictionary is its value. You just tried to assign a dictionary that consists of {"resample" : {...}} with out any key.

If you try this, it works as expected:

    pipeline = {
        "resample" : {"type" : "trans", "name" : "resample", "kwargs" : {"rule" : "1min"}}
    }

    print(pipeline)
#{'resample': {'type': 'trans', 'name': 'resample', 'kwargs': {'rule': '1min'}}}

Upvotes: 0

BHC
BHC

Reputation: 989

While I think you may have just meant to use one fewer pair of curly braces, I thought I'd explain why you get the output you do. The error can be best understood by understanding how Python implements dictionaries (and sets, which are implemented using dictionaries).

A dictionary is an associative array. When you write mydict['foo'] = bar Python 'hashes' the string 'foo' into a numeric value and uses this value decide in which memory location to place bar. When you want to access the value of 'foo' later, Python again hashes 'foo', generates the numerical value and looks in the memory location that the value corresponds to.

Let's for a minute assume that in your error line you defined a dictionary and not a set by assigning a value. You would have something which looks like:

keydict = {'foo': bar}
mydict[keydict] = baz

Now Python has to somehow come up with a numeric value using your dictionary {'foo': bar} which will map to the memory location in which to store baz. Even if you could think of a way to turn a dictionary into a numeric value, the issue is that dictionaries are mutable. If you were to add an element to keydict and then convert it using your method into a numeric value, it wouldn't be the same numeric value as before. Hence you would no longer know where to look to find baz.

The unhashable type error appears because dictionaries are mutable, and therefore their numeric hash value can change. When, in your first line, you place your dictionary in a set, Python tries to hash it to decide in which memory location it should be stored. On noticing that it is a mutable type, the error is thrown.

Upvotes: 1

Arkistarvh Kltzuonstev
Arkistarvh Kltzuonstev

Reputation: 6920

Because you can't keep dictionary items inside set. When you try to declare

pipeline = {
    {"resample" : {"type" : "trans", "name" : "resample", "kwargs" : {"rule" : "1min"}}}
}

You are basically trying to create a set which has its first item a dictionary which is :

{"resample" : {"type" : "trans", "name" : "resample", "kwargs" : {"rule" : "1min"}}}

But, you can always assign pipeline to this dictionary separately. Sets require items to be hashable. Dictionaries themselves are not hashable in python. You can try this in the terminal with any dictionary. Try hash({1: 'a', 2: 'b'}) and it should give you same TypeError: unhashable type: 'dict' error.

Upvotes: 1

Related Questions