I was a bit surprised when I tried to do
if list in dict:
and got
TypeError: unhashable type: 'list'
I know it does not make sense to use lists as keys as they are mutable and their hash could change when you do operations on them. However, why is it not possible to use them to simply look up objects in a dictionary? I know it is not much work doing
if tuple(list) in dict:
rather than just
if list in dict:
But still, I feel like it would work as default behavior as the hash of its current elements should be the exact same thing as the hash of the corresponding tuple that may be in the dictionary? Or am I missing something in what makes lists unusable in dictionaries?
CodePudding user response:
While I don't think "why does Python work like that" questions are on-topic for this site, I'm gonna say this seems like a terrible idea. You are not supposed to (cannot) use lists as keys in a dictionary, so why would you expect them to be among the keys? If you are looking for a tuple, why would you want to pass a list instead?
CodePudding user response:
Actually, you can calculate hash of a list
(as any other sequence of bits) and implement desired behavior.
Hovewer,
tuple
s are immutable objects, hash of atuple
may be calculated once, at initializationlist
s are mutable. They may change its state and hashing based on elements of alist
will produce different hashes, if state was changed. So, using this hashing method, hash oflist
can't be precalculated
Now consider in
operation.
When you check a_tuple in a_dict
, hash of a_tuple
is known, and in
operation takes linear time O(len(a_dict))
.
Suppose, that someone implemented a_list in a_dict
operation. This would take O(len(a_list))
O(len(a_dict))
time, because you have to calculate hash of a_list
. Therefore, unintended behavior happens.
On other hand, if we consider another hashing method that takes O(1), e.g. just by link to an object. You will get another behavior of a_list in a_dict
. Because if a_list == b_list
and not a_list is b_list
, then (a_list in a_dict) != (b_list in a_dict)
.
Also, notice that
Tuples can be used as keys if they contain only strings, numbers, or tuples