Матрица в качестве словарного ключа - PullRequest
6 голосов
/ 11 января 2012

Я только начал использовать numpy и его модуль matrix (очень и очень полезно!), И я хотел использовать матричный объект в качестве ключа словаря, поэтому я проверил, есть ли у matrix __hash__ реализованный метод:

>>> from numpy import matrix
>>> hasattr(matrix, '__hash__')
True

И это так!Хорошо, значит, это может быть ключом словаря:

>>> m1 = matrix('1 2 3; 4 5 6; 7 8 9')
>>> m1
matrix([[1, 2, 3],
        [4, 5, 6],
        [7, 8, 9]])
>>> m2 = matrix('1 0 0; 0 1 0; 0 0 1')
>>> m2
matrix([[1, 0, 0],
        [0, 1, 0],
        [0, 0, 1]])
>>> matrix_dict = {m1: 'first', m2: 'second'}

Сработало!Теперь давайте продолжим тестирование:

>>> matrix_dict[m1]
'first'
>>> matrix_dict[matrix('1 2 3; 4 5 6; 7 8 9')]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: matrix([[1, 2, 3],
                  [4, 5, 6],
                  [7, 8, 9]])

Что?Итак, он работает для той же матрицы, но не работает для другой матрицы с точно таким же содержимым?Давайте посмотрим, что возвращает __hash__:

>>> hash(m1)
2777620
>>> same_as_m = matrix('1 2 3; 4 5 6; 7 8 9')
>>> hash(same_as_m)
-9223372036851998151
>>> hash(matrix('1 2 3; 4 5 6; 7 8 9')) # same as m too
2777665

Итак, метод __hash__ matrix из numpy возвращает разные значения для одного и того же matrix.

Isэто право?Значит ли это, что его нельзя использовать в качестве ключа словаря?И если он не может быть использован, почему он __hash__ реализован?

1 Ответ

9 голосов
/ 11 января 2012

Было бы неправильно использовать изменяемый объект в качестве ключа словаря, потому что его хэш должен измениться, как только вы измените данные, но значение, используемое при вставке, будет сохранено.

В моих тестах numpy на Python 3.2.2 вызывает ошибку типа:

TypeError: unhashable type: 'matrix'

Но в Python 2.7 он по-прежнему допускает хэширование, но значение хэша никогда не меняется при изменении данных, поэтому оно довольно бесполезно в качестве ключа словаря, поскольку добавление в словарь многих объектов matrix, имеющих одинаковый хэш, приведет к ухудшению хэш-таблицы поэтому вставка будет O(n^2) вместо O(1).

Возможно, они не удалили значение хеша, чтобы избежать взлома некоторого API на Python 2.x, но не полагайтесь на него!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...