mirror of https://github.com/jab/bidict.git
60 lines
1.5 KiB
PHP
60 lines
1.5 KiB
PHP
Different Values, Same Hash
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
Consider the following::
|
|
|
|
>>> d = {1: 'one'}
|
|
>>> d[1.0] = 'one point oh'
|
|
|
|
What do you expect to happen next?
|
|
If you expected *d* to become *{1: 'one', 1.0: 'one point oh'}*,
|
|
the actual result might surprise you::
|
|
|
|
>>> d
|
|
{1: 'one point oh'}
|
|
|
|
Unfazed? How about this::
|
|
|
|
>>> d[True] = 'true'
|
|
>>> d
|
|
{1: 'true'}
|
|
>>> d = dict([(1, 'one'), (1.0, 'one point oh'), (1+0j, 'imaginary!'), (True, 'true')])
|
|
>>> d
|
|
{1: 'true'}
|
|
|
|
Kudos if this behavior is old hat to you.
|
|
Otherwise, take heed:
|
|
In Python,
|
|
these equivalent values all have the same hash value,
|
|
and therefore can only occupy the same single spot
|
|
in a set or dictionary::
|
|
|
|
>>> hash(1) == hash(1.0) == hash(1+0j) == hash(True)
|
|
True
|
|
>>> hash(0) == hash(0.0) == hash(0j) == hash(False)
|
|
True
|
|
>>> len({0, 0.0, 0j, False})
|
|
1
|
|
|
|
As demonstrated above,
|
|
mutating operations using a (hash-)equivalent but not identical key are
|
|
type-insensitive but type-preserving with respect to the existing key.
|
|
|
|
With bidict,
|
|
since values function like keys in the inverse mapping,
|
|
the implications of this behavior apply on both sides.
|
|
For example::
|
|
|
|
>>> from bidict import bidict
|
|
>>> b = bidict({1: 1})
|
|
>>> b.inv[True]
|
|
1
|
|
>>> b[2] = True
|
|
Traceback (most recent call last):
|
|
...
|
|
ValueExistsException: Value 1 exists with key 1
|
|
>>> b.put(True, 'true')
|
|
Traceback (most recent call last):
|
|
...
|
|
KeyExistsException: Key 1 exists with value 1
|