Есть ли способ в Python для запроса dict / set с известным значением хеша - PullRequest
0 голосов
/ 04 марта 2019

Предположим, что объект a имеет очень дорогую хеш-функцию, и я хочу запросить a в разных диктовках или наборах.Если я сделаю это наивно:

d1_res = d1[a]
d2_res = d2[a]

Мне придется сделать два хэша.Я хочу что-то вроде:

РЕДАКТИРОВАТЬ: следующий код в исходном вопросе является неправильным!

hashvalue = hash(a)
d1_res = d1.getitem(a, hashvalue=hash)
d2_res = d2.getitem(a, hashvalue=hash)

РЕДАКТИРОВАТЬ: Это правильный примеркод

hashvalue = hash(a)
d1_res = d1.getitem(a, hashvalue=hashvalue)
d2_res = d2.getitem(a, hashvalue=hashvalue)

Таким образом, мне нужно сделать только один хэш.Есть ли способ для этого?Или существует какой-либо механизм Python, который предотвращает такой интерфейс?

РЕДАКТИРОВАТЬ: важно следующее сообщение

Кажется, что простое решение кэширует результат хеширования в __hash__ метод, но мой пример здесь упрощенный.На самом деле, хеш-функция в моем реальном случае не дорогая (просто int hash).Но хеширование выполняется много раз, и я хочу сократить расходы.Я пишу расширение C / C ++, поэтому я ищу любое возможное улучшение производительности.

Заранее спасибо.

1 Ответ

0 голосов
/ 04 марта 2019

Вот идея, которая будет использовать сам объект (ключ dict) для хранения своего хэша.

Реализация dict не должна знать - она ​​просто вызовет хэш .

Каждый «установщик» сделает значение кэшированного хэша None и вызовет пересчет.

class MyComplexObject:
    def __init__(self, name, size):
        self._name = name
        self._size = size
        self.hash_value = None

    def __hash__(self):
        if self.hash_value is None:
            #  heavy calculations goes here
            #  the result of the calculations is 7 (as an example)
            self.hash_value = 7
        return self.hash_value

    @property
    def name(self):
        return self._name

    @name.setter
    def name(self, name):
        self._name = name
        self.hash_value = None

    @property
    def size(self):
        return self._size

    @size.setter
    def size(self, size):
        self._size = size
        self.hash_value = None
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...