Одна из основных структур данных в Python - это словарь, который позволяет записывать «ключи» для поиска «значений» любого типа. Это реализовано внутри как хеш-таблица? Если нет, то что это?
Одна из основных структур данных в Python - это словарь, который позволяет записывать «ключи» для поиска «значений» любого типа. Это реализовано внутри как хеш-таблица? Если нет, то что это?
Ответы:
Да, это хэш-отображение или хеш-таблица. Вы можете прочитать описание реализации dict в python, написанное Тимом Питерсом, здесь .
Вот почему вы не можете использовать что-то «не хэшируемое» в качестве ключа, как список:
>>> a = {}
>>> b = ['some', 'list']
>>> hash(b)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: list objects are unhashable
>>> a[b] = 'some'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: list objects are unhashable
Вы можете прочитать больше о хеш-таблицах или проверить, как это было реализовано в python и почему это реализовано таким образом .
.keys()
можно получить список ключей. Настоящая хеш-таблица не хранит ключи, а просто хэши для экономии места.
Для словаря Python должно быть нечто большее, чем поиск по таблице в hash (). Путем грубого эксперимента я обнаружил это столкновение хэшей :
>>> hash(1.1)
2040142438
>>> hash(4504.1)
2040142438
Все же это не ломает словарь:
>>> d = { 1.1: 'a', 4504.1: 'b' }
>>> d[1.1]
'a'
>>> d[4504.1]
'b'
Санитарная проверка:
>>> for k,v in d.items(): print(hash(k))
2040142438
2040142438
Возможно, есть еще один уровень поиска помимо hash (), который позволяет избежать коллизий между ключами словаря. Или, возможно, dict () использует другой хеш.
(Кстати, это в Python 2.7.10. Та же история в Python 3.4.3 и 3.5.0 со столкновением в hash(1.1) == hash(214748749.8)
.)
hash('I wandered lonely as a cloud, that drifts on high o\'er vales and hills, when all at once, I saw a crowd, a host of golden daffodils.')
Это дает десятичную цифру из 19 цифр - -4037225020714749784
если вы достаточно дерзкий, чтобы заботиться. Продолжайте в своих словах, дети, и хэш по-прежнему состоит из 19 цифр. Я предполагаю, что есть ограничение на длину строки, которую вы можете хэшировать в Python, но можно с уверенностью сказать, что число возможных строк больше, чем возможных значений. И hash(False)
= 0 кстати.
Да. Внутренне это реализовано как открытое хеширование на основе примитивного полинома над Z / 2 ( источник ).
Чтобы расширить объяснение Носкло:
a = {}
b = ['some', 'list']
a[b] = 'some' # this won't work
a[tuple(b)] = 'some' # this will, same as a['some', 'list']
dict
реализации Python .