Reputation: 1558
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
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
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
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