PyThrone
15 subscribers
12 photos
Download Telegram
class Some:
def __hash__(self):
return 1

def __eq__(self, other):
return False


d = {Some() for _ in range(5)}

print(len(d))


Что выведет этот код?

Может показаться, что ответ = 1, т.к. hash любого инстанса класса Some равен 1.

1) При добавлении нового элемента в set, dict питон находит его hash(element) (если вы не знаете, что такое хэш функция и зачем она нужна, почитайте про хэш таблицы).

2) Из этого хэша определяется индекс в массиве, куда нужно вставить этот элемент.

3) Если по этому индексу ничего нет, то элемент просто вставляется.

4) А если там уже есть какой-то элемент (это коллизия), то питон уже сравнивает существуещий элемент с тем, который хотим добавить (new == old). Если они равны, то старый заменяется новым элементом.

5) В нашем случае все экземпляры Some разные, т.к.
__eq__ всегда возвращает False


Поэтому ответ 5.

#set #dict #hash
🔥3
Что выведет этот код?

hash() - функция, которая возвращает хэш-значение объекта, если объект хэшируемый (имеет __hash__).

Хэш-значение это всегда целое число.

Хэш-значение целых чисел есть само целое число. Но в зависимости от разрядности платформы. Если у Вас 64-битовая платформа, то hash() вернет значение от -2^63 до 2^63-1.

Хорошо, что насчет нашего кода?

True - имеет hash = 1

print(hash(True)) # 1
print(isinstance(True, int)) # True
print(True == 1) # True


1 - int в допустимом диапазоне, поэтому hash() вернет его же.

И для всех чисел, которые равны какому то целому числу, хэш функция вернет это целое число:

print(1 == 1.0) # True
print(hash(1.0)) # 1


А в классе Item мы переопределили два метода:
__hash()__ -> 1
и __eq__ -> 1 == other

item = Item()
print(1 == item) # True
print(hash(item)) # 1


В итоге получается, что все ключи равны и у всех ключей одно и то же хэш-значение.

Поэтому ответ 1.

#hash #числа
👍3