Какими могут быть ключи словарей и причем тут hash()?
Вставка
- Опубліковано 16 вер 2024
- Если спросить начинающего разработчика, какие типы данных могут быть ключами словарей, ответ будет "строки". Более опытный разработчик скажет, что ключами словаря может быть любой иммутабельный тип данных. Но это тоже не совсем правильно. Давайте разбираться!
Я в Telegram - t.me/tricky_py...
Канал создан при поддержке сообщества Moscow Python.
Наш UA-cam-канал - / @moscowdjangoru
Курсы Learn Python - learn.python.ru/
Спасибо за очень интересный пример работы с csv files.
Просто прекрасно!!!
Благодарю!
Автор, ну как тут дизлайк то не влепить?
Почему абсолютно все "учителя" объясняют все через пень колоду?
3:13 Если ключи словаря преобразуются в набор хешей, тогда почему мы можем создавать словарь типа
{"":"Empty string",0:"Zero"}
У пустой строки и целого числа ноль одинаковый хеш, однако ключи разные.
Почему ты нифига не объяснил, что во время создания словаря производится не только запуск функции
hash() (или метода __hash__ в пользовательском классе), но и функция сравнения (__eq__ в пользовательском классе), но только в случае если хеши равны?
0:26 Атрибут __hash__ есть у всех, ты не поверишь. Он есть у класса object, от которого унаследованны все остальные. Только этот атрибут может быть перегружен и иметь значение None, например у списка.
Представь себе, буду я проверять объект на возможность использования в качестве ключа, напишу вроде
hasattr( MyObject, __hash__), он мне вернет True, и я смачно сяду в лужу.
Потом вообще началась какая-то дичь. Какой то нафиг нам не нужный модуль csv, и больше ни слова про хеш.
Кстати, изменяемые типы данных тоже могут быть ключами словаря. Например это функции, или пользовательские классы, которые в качестве атрибута могут иметь список.
А вот использовать в словаре например булевы значения и цифры надо осторожно. Ибо True преобразуется в 1, а False - в 0.
В общем, изучать програмирование можно только методом научного тыка.
👍👍👍
Может ли быть такое что тип хешируемый, но мутабельный? Что тогда?
Мне к примеру не совсем понятно требование к немутабельности. Возникают вопросы при создании пользовательских классов, что внем нужно определять итп. и как это согласуется с немутабельностью
В пятницу выложу вторую часть видео - там будет про то, как управлять хешированием своих объектов. В том числе про мутабельность в этом разрезе немного поговорю. Краткий ответ - если сделать свой класс, объявить у него __hash__(), инстанцировать и сделать объект ключом словаря и потом поменять - будет KeyError
Если мы можем достучаться до исходного объекта (храним его ещё где то) и можем запросить его в качестве ключа - никаких проблем. Например экземпляры классов или функции могут быть ключами словаря, хотя они мутабельны. Если написать кривую реализацию хеширования у своего класса и начать использовать его в качестве ключа, возможны всякие странности. Например сделать так, чтобы __hash__() возвращал случайное число. Тогда мы сможем сколько угодно раз класть один и тот же объект в словарь в виде ключа или как элемент во множество, но не сможем его оттуда достать.
Интересно, какими могут быть значения множеств и причём там hash? Не нашёл информации об устройстве set в python.
Тоже самое, все элементы множества должны быть хэшируемыми
@@user-kt2vw4iv6y это понятно, но как именно setы устроены не понятно.
У списков, словарей, множеств и bytearray также есть методы __hash__ и __eq__ однако это не делает их хешируемыми
Правильный ответ: Ключом в словаре может быть любой не изменяемый тип данных
hash([1,2,3]) будет ошибка TypeError: unhashable type: 'list'
поэтому не у всех есть hash
можно без импорта воспользоваться встроенным методом setdefault.
dict.setdefault(key, default).append(value)
В каждой сессии хэш будет отличаться (кроме целых чисел) потому что базово он формируется алгоритмом от id объекта, а при перезапуске сессии место объектов в памяти будет меняться?
Нет, не поэтому. id целых чисел тоже ведь меняется со сменой сессии. Дело в том, как я это понимаю, что длинное число, являющееся хэшем, каждый раз вычисляется заново хэш-функцией, с помощью особых хитрых алгоритмов, и оно должно быть уникально. И это число именно вычисляется, а не назначается исходя из каких-то параметров. Для целых чисел это делать не надо, так как каждое целое число уникально само по себе, поэтому и хэш этого числа приравнивается самому числу. И это же абсолютно исключает коллизии для целых чисел.
+1
Какими могут быть ключи словарей и причем тут hash()? на вопрос ответа в видео нет