Функция hash() в Python
avatar
7 | (offline)
❤️‍🔥Notehunter Developer
Добавлено:
Категория: Основы «Python»
Комментариев: 0

Прежде чем ознакомиться с функцией hash() в Python, давайте разберемся, что такое хеширование.

Что такое хеширование?

Хэширование - функция, осуществляющая преобразование массива входных данных произвольной длины в выходную битовую строку установленной длины, выполняемое определённым алгоритмом. Преобразование, производимое хеш-функцией, называется хешированием.

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

Процесс хэширования включает в себя преобразование заданного ключа в другое значение. Хэш-функция используется для генерации нового значения в соответствии с математическим алгоритмом. Результат хэш-функции известен как хеш-значение.

Что такое hash функция в Python?

hash() в Python - это встроенная функция, которая используется для возврата хэш-значения данного объекта. Хэш-значения - это целые числа, которые полезны при сравнении ключей словаря во время поиска словаря, при котором поиск значения данного ключа в функции словаря. hash() работает только для неизменяемых объектов.

Неизменяемые объекты в Python: bool,int, float, tuple, string, frozenset.

Синтаксис:

hash(object)

Аргументы:

  • Функция принимает один объект в качестве аргумента, чтобы вернуть его хеш-значение.

Давайте рассмотрим примеры хеширования:

# Для чисел
print('Хеш-значение:', hash(23))
# Для чисел с плавающей точкой
print('Хеш-значение:', hash(29.30))
# Для строк
print('Хеш-значение:', hash('Kuban Cossacks'))
# Для кортежа
print('Хеш-значение:', hash(tuple((1, 2, 3, 4, 5))))
# Для неизменяемого множества
print('Хеш-значение:', hash(frozenset((1, 2, 3, 4, 5))))

Результаты:

>>> Хеш-значение: 23
>>> Хеш-значение: 691752902764109853
>>> Хеш-значение: -1969214143514591502
>>> Хеш-значение: -5659871693760987716
>>> Хеш-значение: -3779889356588604112

Если мы передадим изменяемый объект, например список (list), то получим ошибку: ​​TypeError: unhashable type: 'list'

# Список (изменяемый объект)
print('Хеш-значение:', hash(list((1, 2, 3, 4, 5))))

Результат:

>>> Traceback (most recent call last):
>>>   File "C:\Users\Razilator\Desktop\Projects\Coding\articles\hash\main.py", line 2, in <module>
>>>     print('Хеш-значение:', hash(list((1, 2, 3, 4, 5))))
>>> TypeError: unhashable type: 'list'

Если сравнивать целочисленные значения с числами с плавающей точкой методом хеширования, они будут также равны между собой, как бы если бы мы указали просто 2 == 2.0

print(hash(23) == hash(23.0))
print(hash(29.0) == 29)
print(29 == hash(29.0))

Результат:

>>> True
>>> True
>>> True

Использование функции hash() в объектах:

Пример:

class Student:

    def __init__(self, name, city):

        self.name = name
        self.city = city


student_1 = Student('Vladislav', 'Moscow')
student_2 = Student('Vladislav', 'Moscow')

print('Хеш-значение для student_1', hash(student_1))
print('Хеш-значение для student_2', hash(student_2))


if student_1 == student_2:
    print('Один и тот-же студент')
else:
    print('Разные студенты')

Результат:

>>> Хеш-значение для student_1 103001664509
>>> Хеш-значение для student_2 103001664497
>>> Разные студенты

Мы видим, что, хотя значения атрибутов обоих объектов одинаковы, результат сравнения двух объектов не равен. Что мы можем сделать, так это создать таможенный специальный метод, чтобы справиться с этим. Это специальный метод __eq__, который будет сравнивать значения атрибутов и соответственно возвращать значение True или False.

class Student:

    def __init__(self, name, city):

        self.name = name
        self.city = city

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


student_1 = Student('Vladislav', 'Moscow')
student_2 = Student('Vladislav', 'Moscow')

#print('Хеш-значение для student_1', hash(student_1))
#print('Хеш-значение для student_2', hash(student_2))


if student_1 == student_2:
    print('Один и тот-же студент')
else:
    print('Разные студенты')

Результат:

>>> Один и тот-же студент

Но если мы захотим узнать хеш-значение, то получим ошибку: ​TypeError: unhashable type: 'Student'

Чтобы преодолеть эту проблему, необходимо использовать метод __hash__()

class Student:

    def __init__(self, name, city):

        self.name = name
        self.city = city

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

    def __hash__(self):
        return hash((self.name, self.city))


student_1 = Student('Vladislav', 'Moscow')
student_2 = Student('Vladislav', 'Moscow')

print('Хеш-значение для student_1', hash(student_1))
print('Хеш-значение для student_2', hash(student_2))


if student_1 == student_2:
    print('Один и тот-же студент')
else:
    print('Разные студенты')

Результат:

>>> Хеш-значение для student_1 6182727541821412174
>>> Хеш-значение для student_2 6182727541821412174
>>> Один и тот-же студент

И если мы изменим значения, то студенты не будут равны друг другу:

class Student:

    def __init__(self, name, city):

        self.name = name
        self.city = city

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

    def __hash__(self):
        return hash((self.name, self.city))


student_1 = Student('Vladislav', 'Moscow')
student_2 = Student('Vladislav', 'Moscow')

student_2.name = 'Natali'
student_2.city = 'Tomsk'

print('Хеш-значение для student_1', hash(student_1))
print('Хеш-значение для student_2', hash(student_2))


if student_1 == student_2:
    print('Один и тот-же студент')
else:
    print('Разные студенты')

Результат:

>>> Хеш-значение для student_1 49386540312254370
>>> Хеш-значение для student_2 2735435424243624172
>>> Разные студенты
Теги записи: Python, Основы Python, hash(),
Комментарии к статье 0
Комментариев нет
Форма добавления комментария (необходима регистрация)