numpy float64s as keys to a dict

Viewed 1599

If I have a dict whose keys are numpy float64 numbers, how do I can access them by key value?

>>> keys = np.arange(0, 0.5, 0.05, dtype=np.float64)
>>> keys
    array([...,  0.3 ,  ...])

    # The following creates a dicionary lookup table
    # data[x] = exp(x) for all x in keys

>>> data = {key: np.exp(key) for key in keys}
>>> data[0.3]
    KeyError: 0.3
>>> data[np.float64(0.3)]
    KeyError: 0.29999999999999999
>>> data.keys()
[..., 0.30000000000000004, ...]

Do numpy floats even have the capability to be used as keys to a dict?

2 Answers

For various reasons described in comments and the other answer, this will often be a bad idea, especially for "production quality" source code. However, if we're just working on a quick and dirty python script, it can sometimes be useful to try it anyway.

One solution that seems fairly reliable so far to me is to use the round() function to make sure that all the numbers in keys are identical to numbers that we as humans would type with only a handful of decimals. For example (using Python 3.6):

>>> import numpy as np
>>> keys = [round(key, 4) for key in np.arange(0, 0.5, 0.05, dtype=np.float64)]
>>> keys
    [0.0, 0.050000000000000003, 0.10000000000000001, 0.14999999999999999, 0.20000000000000001, 0.25, 0.29999999999999999, 0.34999999999999998, 0.40000000000000002, 0.45000000000000001]
>>> data = {key: np.exp(key) for key in keys}
>>> data[0.3]
    1.3498588075760032
>>> data[np.float64(0.3)]
    1.3498588075760032
>>> data.keys()
    dict_keys([0.0, 0.050000000000000003, 0.10000000000000001, 0.14999999999999999, 0.20000000000000001, 0.25, 0.29999999999999999, 0.34999999999999998, 0.40000000000000002, 0.45000000000000001])

The keys can still have lots of decimals due to internal (floating-point) representation, but at least they'll be consistent with new floats that us humans would type, like 0.3.

Related