It is well known that mutable types cannot be the key of a dictionary.
However if you were using say C++, then regular maps let you use vectors and arrays as map keys because regular maps are implemented as trees.
However, C++ also lets you use an array as the key of an unordered map, which is closer in spirit to a python dictionary because it hashes the keys as long as you provide the hash function for types it doesn't know how to hash.
So I wanted to know if Python would let you do the same as long as you provide an __hash__
method.
In [1]: b = {}
In [2]: class hlist(list):
...: def __hash__(self):
...: temp = []
...: for item in self:
...: print item
...: temp.append(item)
...: return hash(tuple(temp))
...:
In [3]: a = hlist([1,2,3,4])
In [4]: c = hlist([1,2,3,4])
In [5]: b[a] = "car"
1
2
3
4
In [6]: b[c]
1
2
3
4
Out[6]: 'car'
In [7]: a.append(5)
In [8]: b[c]
1
2
3
4
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-8-013e994efe63> in <module>()
----> 1 b[c]
KeyError: [1, 2, 3, 4]
I added the print
inside the __hash__
to figure out what is being hashed and when the function is invoked.
Right before the KeyError
is thrown, the contents of c
are printed, indicated that c
was just hashed. Now shouldn't it just check if this hash value if the hash value of one of the keys? Why does it throw a key error?
If it is also hashing all the keys one by one to figure out if one of them hash the same hash value as the query shouldn't the code below work?
In [11]: b[hlist([1,2,3,4,5])]
1
2
3
4
5
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-11-09593553a69b> in <module>()
----> 1 b[hlist([1,2,3,4,5])]
KeyError: [1, 2, 3, 4, 5]
If you were determined to have a mutable key with a semi robust hashing function similar to cpp is it possible?