Можно ли извлечь данные из словаря, используя ХЕШ ключа?

Добрый день! 

У нас имеется Python 3.8, и в одной из задач было необходимо организовать хранение данных в словаре с последующей конвертацией в JSON. В данном словаре в качестве ключа используется экземпляр класса "test", а значением является строка (условный пример). 

Вопрос: существует ли способ получить доступ к "ключу" в словаре, если мы имеем (или ранее сохранили) его значение? Я понимаю, что это не самый оптимальный подход, но мне все равно интересно. 

<pre><code class="python">class test:
    def __init__(self):
        self.key = ''
        self.p1  = 0
        self.p2  = 0
        self.p3  = 0
        self.my_hash = None


    def __hash__(self):
        self.my_hash = hash(self.key)
        return hash(self.my_hash)

    def __eq__(self, other):
        return other and self.key == other.key


tmp_dict = {}
tmp = test()
tmp.key = "test_1"

tmp_hash = tmp.__hash__()
print(tmp_hash)

tmp_dict[tmp] = "value by key 'test_1'"

print(tmp_dict[tmp])
print(tmp_dict[tmp_hash]) &lt;-- ?</code></pre>
  • 31 октября 2024 г. 6:22
Ответы на вопрос 2
Добрый день!

В Python, когда вы используете объекты в качестве ключей словаря, то они хранятся в словаре при помощи их хеш-значений и сравнения на равенство (через метод `__eq__`). Таким образом, для доступа к значению по ключу, вам нужно использовать сам объект, а не его хеш. 

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

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

Ниже приведён пример, как это сделать:

```python
class test:
    def __init__(self):
        self.key = ''
    
    def __hash__(self):
        return hash(self.key)

    def __eq__(self, other):
        return isinstance(other, test) and self.key == other.key

tmp_dict = {}
reverse_dict = {}

# Создание объекта и добавление в словарь
tmp = test()
tmp.key = "test_1"
tmp_dict[tmp] = "value by key 'test_1'"
reverse_dict["value by key 'test_1'"] = tmp  # Обратный индекс

# Теперь мы можем получить объект по значению
value = "value by key 'test_1'"
if value in reverse_dict:
    key_object = reverse_dict[value]
    print(tmp_dict[key_object])  # Вывод: value by key 'test_1'
```

В этом коде мы создаём дополнительный `reverse_dict`, который позволяет нам осуществлять обратный поиск (значение -> ключ) по словарю. 

Если у вас есть ещё вопросы, не стесняйтесь спрашивать!
А как быть с коллизиями? Не забывай, что хэши не уникальны
Похожие вопросы