Однією з основних структур даних в Python є словник, який дозволяє записувати "клавіші" для пошуку "значень" будь-якого типу. Чи реалізується це внутрішньо як хеш-таблиця? Якщо ні, то що це?
Однією з основних структур даних в Python є словник, який дозволяє записувати "клавіші" для пошуку "значень" будь-якого типу. Чи реалізується це внутрішньо як хеш-таблиця? Якщо ні, то що це?
Відповіді:
Так, це хеш-карта або хеш-таблиця. Ви можете прочитати опис реалізації диктону python, написаний Тімом Петерсом, тут .
Ось чому ви не можете використовувати щось "не доступне" як клавішу 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
Ви можете прочитати більше про хеш-таблиці або перевірити, як це було реалізовано в python і чому він реалізований таким чином .
.keys()
можна отримати список ключів. Справжня хеш-таблиця не зберігатиме ключі, а хеші, щоб заощадити місце.
У словнику Python повинно бути більше, ніж пошук таблиці на хеш (). Шляхом грубого експерименту я виявив таке хеш-зіткнення :
>>> 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
Можливо, є інший рівень пошуку за межами хеша (), який дозволяє уникнути зіткнень між клавішами словника. А може бути, 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 ( джерело ).
Щоб розширити пояснення nosklo:
a = {}
b = ['some', 'list']
a[b] = 'some' # this won't work
a[tuple(b)] = 'some' # this will, same as a['some', 'list']
dict
реалізації Python .