Description
Documentation
Unlike sequences, which are indexed by a range of numbers, dictionaries are indexed by keys, which can be any immutable type; strings and numbers can always be keys. Tuples can be used as keys if they contain only strings, numbers, or tuples; if a tuple contains any mutable object either directly or indirectly, it cannot be used as a key. You can’t use lists as keys, since lists can be modified in place using index assignments, slice assignments, or methods like append() and extend().
Formally, mutability is not the reason why you can't use lists as keys, the only factor that matters is hashability, and it was decided to make list
unhashable to avoid "undesirable side effects". This is articulated in the DictionaryKeys section of the Python Wiki.
Consider this:
class HashableList(list):
def __hash__(self):
return id(self)
key = HashableList([1, 2])
d = {key: True}
key.append(3)
print(d) # prints {[1, 2, 3]: True}
This code, albeit weird, is perfectly valid. Clearly, .append()
is not what prevents lists from being used as keys.
While mutability might be a reason why you shouldn't use something as a key, it's never the reason why you can't. This section in the tutorial doesn't make it clear and could bring more confusion about the inner workings, and the part of the documentation emphasised in italic is factually false.
I suggest rephrasing the section to clarify that the primary requirement for dictionary keys is hashability, not immutability. While many immutable types are hashable by default in Python, the two concepts are distinct.