Is a Python dictionary an example of a hash table?
--
Music by Eric Matyas
https://www.soundimage.org
Track title: Lost Civilization
--
Chapters
00:00 Question
00:29 Accepted answer (Score 313)
01:10 Answer 2 (Score 52)
02:35 Answer 3 (Score 22)
02:52 Answer 4 (Score 8)
03:07 Thank you
--
Full question
https://stackoverflow.com/questions/1148...
Accepted answer links:
[here]: http://mail.python.org/pipermail/python-...
[read more about hash tables]: http://en.wikipedia.org/wiki/Hash_table
[check how it has been implemented in python]: https://hg.python.org/cpython/file/10eea...
[why it is implemented that way]: https://hg.python.org/cpython/file/10eea...
Answer 3 links:
[source]: https://mail.python.org/pipermail/python...
--
Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...
--
Tags
#python #hash #dictionary #hashmap #hashtable
#avk47
ACCEPTED ANSWER
Score 323
Yes, it is a hash mapping or hash table. You can read a description of python's dict implementation, as written by Tim Peters, here.
That's why you can't use something 'not hashable' as a dict key, like a list:
>>> 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
You can read more about hash tables or check how it has been implemented in python and why it is implemented that way.
ANSWER 2
Score 56
There must be more to a Python dictionary than a table lookup on hash(). By brute experimentation I found this hash collision:
>>> hash(1.1)
2040142438
>>> hash(4504.1)
2040142438
Yet it doesn't break the dictionary:
>>> d = { 1.1: 'a', 4504.1: 'b' }
>>> d[1.1]
'a'
>>> d[4504.1]
'b'
Sanity check:
>>> for k,v in d.items(): print(hash(k))
2040142438
2040142438
Possibly there's another lookup level beyond hash() that avoids collisions between dictionary keys. Or maybe dict() uses a different hash.
(By the way, this in Python 2.7.10. Same story in Python 3.4.3 and 3.5.0 with a collision at hash(1.1) == hash(214748749.8).)
(I haven't found any collisions in Python 3.9.6. Since the hashes are bigger -- hash(1.1) == 230584300921369601 -- I estimate it would take my desktop a thousand years to find one. So I'll get back to you on this.)
ANSWER 3
Score 23
Yes. Internally it is implemented as open hashing based on a primitive polynomial over Z/2 (source).
ANSWER 4
Score 9
To expand upon nosklo's explanation:
a = {}
b = ['some', 'list']
a[b] = 'some' # this won't work
a[tuple(b)] = 'some' # this will, same as a['some', 'list']