Why make lists inept?

A common SO problem is removing duplicates from a list of lists . As the lists resolve, set([[1, 2], [3, 4], [1, 2]])throws TypeError: unhashable type: 'list'. The answers to this question are usually associated with the use of tuples, which are immutable and therefore hashed.

This answer to What makes lists unhashable? include the following:

If the hash value changes after it is stored in a specific slot in the dictionary, this will lead to an inconsistent dictionary. For example, a list would initially be stored at location A, which was determined based on a hash value. If the hash value changes, and if we look for the list, we may not find it in location A or according to the new hash value, we could find some other object.

but I do not quite understand, because other types that can be used for dictionary keys can be changed without problems:

>>> d = {}
>>> a = 1234
>>> d[a] = 'foo'
>>> a += 1
>>> d[a] = 'bar'
>>> d
{1234: 'foo', 1235: 'bar'}

, a , . ? , , , ?

>>> class my_list(list):
...   def __hash__(self):
...     return tuple(self).__hash__()
...
>>> a = my_list([1, 2])
>>> b = my_list([3, 4])
>>> c = my_list([1, 2])
>>> foo = [a, b, c]
>>> foo
[[1, 2], [3, 4], [1, 2]]
>>> set(foo)
set([[1, 2], [3, 4]])

, set(), ? , , , .

+4
1

, , . a += 1 , int 1235, a. , int, a += 1 , a = a + 1.

1234 . - int 1234 . - , a . .

:

>>> class BadKey:
...     def __init__(self, value):
...         self.value = value
...     def __eq__(self, other):
...         return other == self.value
...     def __hash__(self):
...         return hash(self.value)
...     def __repr__(self):
...         return 'BadKey({!r})'.format(self.value)
...
>>> badkey = BadKey('foo')
>>> d = {badkey: 42}
>>> badkey.value = 'bar'
>>> print(d)
{BadKey('bar'): 42}

, value badkey. . ; , , badkey .

:

>>> badkey in d
False
>>> BadKey('bar') in d
False
>>> for key in d:
...     print(key, key in d)
...
BadKey('bar') False

, .

, badkey ; . , , . , .

. , .

+10

Source: https://habr.com/ru/post/1652206/


All Articles