2008-09-22 4 views
126

Одной из основных структур данных в Python является словарь, который позволяет записывать «ключи» для поиска «значений» любого типа. Является ли это внутренне реализованным как хэш-таблица? Если нет, то что это?Является ли словарь Python примером хэш-таблицы?

+1

Вот разговор Брэндон Craig Rhodes обсуждал, как питон словарных работ , https://www.youtube.com/watch?v=C4Kc8xzcA68. – chandola 2017-05-27 12:11:30

ответ

174

Да, это хеш-карта или хэш-таблица. Вы можете прочитать описание реализации python's dict, как написано Тимом Петерсом, here.

Вот почему вы не можете использовать что-то «не hashable» в качестве ключа Dict, как список:

>>> 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 

Вы можете read more about hash tables или check how it has been implemented in python и why it is implemented that way.

+1

Тим Питерс связывает швы, которые нужно сломать, есть ли там чистая связь? – 2012-06-25 15:42:08

+1

@MattAlcock: Я обновил ссылку. Иногда (обычно из-за того, что кто-то хочет удалить адрес электронной почты где-то) архивы списков python перестраиваются, и идентификаторы электронной почты меняются, тем самым нарушая эти ссылки. Администраторы pydotorg обычно стараются избегать этого в наши дни. – 2012-08-19 09:19:46

+0

Но с помощью `.keys()` можно получить список ключей. Реальная хеш-таблица не сохранит ключи, а просто хеширует, чтобы сэкономить место. – 2016-05-11 20:41:15

17

Да. Внутренне он реализуется как открытое хеширование на основе примитивного многочлена над Z/2 (source).

29

Если вас интересуют технические подробности, одна статья в статье Beautiful Code посвящена внутренним возможностям реализации Python dict.

5

Чтобы расширить на объяснения nosklo в:

a = {} 
b = ['some', 'list'] 
a[b] = 'some' # this won't work 
a[tuple(b)] = 'some' # this will, same as a['some', 'list'] 
11

Там должно быть больше к словарю Python, чем табличного на хэш(). По грубому экспериментированию я нашел это хэш столкновение:

>>> hash(1.1) 
2040142438 
>>> hash(4504.1) 
2040142438 

Но это не нарушает словарь:

>>> d = { 1.1: 'a', 4504.1: 'b' } 
>>> d[1.1] 
'a' 
>>> d[4504.1] 
'b' 

Sanity проверка:

>>> 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).)

Смежные вопросы