Обновление значений в словаре при совпадении пользовательских ключей

Для двух показанных объектов код уже оставляет одну запись со значением 'second'. Реальная проблема — изменяемый список внутри ключа и слабый hash(sum(...)); храните неизменяемый кортеж и хешируйте его.

Короткий ответ

Что ответить на собеседовании

Для двух показанных объектов код уже оставляет одну запись со значением 'second'. Реальная проблема — изменяемый список внутри ключа и слабый hash(sum(...)); храните неизменяемый кортеж и хешируйте его.

Подробный разбор

Ответ с пояснениями

Условие

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

from typing import Any

class HashList:
    def __init__(self, data: list[int]) -> None:
        self._data = data

    def __eq__(self, other: Any) -> bool:
        if isinstance(other, self.__class__):
            return self._data == other._data
        return False

    def __hash__(self) -> int:
        return hash(sum(self._data))

obj1 = HashList([1, 2, 3])
obj2 = HashList([1, 2, 3])

my_dict = {
    obj1: "first",
    obj2: "second",
}

print(my_dict)

Ответ

Для двух показанных объектов код уже оставляет одну запись со значением 'second'. Реальная проблема — изменяемый список внутри ключа и слабый hash(sum(...)); храните неизменяемый кортеж и хешируйте его.

Простой вариант:

from dataclasses import dataclass

@dataclass(frozen=True)
class HashList:
    _data: tuple[int, ...]

    def __init__(self, data):
        object.__setattr__(self, '_data', tuple(data))

Автоматические eq/hash сравнивают и хешируют последовательность целиком. Порядок значим, как и в исходном сравнении списков. Если требуется математическое множество, это другой контракт. Одинаковая сумма разных списков не нарушает корректность словаря сама по себе: коллизии допустимы, но ухудшают распределение. Изменение хеша уже вставленного ключа действительно ломает поиск.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее