36

I'm pretty new to Python numpy. I attempted to use the numpy array as the key in the dictionary in one of my functions and then was told by the Python interpreter that the numpy array is not hashable. I've just found out that one way to work this issue around is to use repr() function to convert a numpy array to a string but it seems very expensive. Is there any better way to achieve the same effect?

Update: I could create a new class to contain the numpy array, which seems to be the right way to achieve what I want. Just wondering if there is any better method.

update 2: Using a class to contain data in the array and then override __hash__ function is acceptable, however, I'd prefer the solution provided by @hpaulj. Converting the array/list to a tuple fits my need in a better way as it does not require an additional class.

6
  • What are you doing that you want to use a numpy array (in whatever form it is) as a dictionary key? Commented Sep 24, 2016 at 9:42
  • You may use the data in numpy array to create a hash which could be used as a key for dictionary. Commented Sep 24, 2016 at 9:43
  • @JonClements I need a dictionary to map a 1-d vector to a set of points Commented Sep 24, 2016 at 9:45
  • @ZdaR Will try that. Cheers Commented Sep 24, 2016 at 9:45
  • 7
    Try tuple(A.tolist()). For a 1d array this conversion is straight forward. Commented Sep 24, 2016 at 13:19

3 Answers 3

38

If you want to quickly store a numpy.ndarray as a key in a dictionary, a fast option is to use ndarray.tobytes() which will return a raw python bytes string which is immutable

my_array = numpy.arange(4).reshape((2,2))
my_dict = {}
my_dict[my_array.tobytes()] = None
Sign up to request clarification or add additional context in comments.

4 Comments

+2 for the efficiency in both the key creation process and the key size.
This is great. Both simple and efficient.
Love this. Exactly what I am looking for.
You have to be careful with hash(array.data.tobytes()) when the arrays are of different shape. For example, np.zeros((2, 1)) and np.zeros((1, 2)) have the same bytes.
13

After done some researches and reading through all comments. I think I've known the answer to my own question so I'd just write them down.

  1. Write a class to contain the data in the array and then override __hash__ function to amend the way how it is hashed as mentioned by ZdaR
  2. Convert this array to a tuple, which makes the list hashable instantaneously.Thanks to hpaulj

I'd prefer method No.2 because it fits my need better, as well as simpler. However, using a class might bring some additional benefits so it could also be useful.

1 Comment

I think its better if you add a code snippet for future readers
-3

I just ran into that issue and there's a very simple solution to it using list comprehension:

import numpy as np

dict = {'key1':1, 'key2':2}
my_array = np.array(['key1', 'key2'])

result = np.array( [dict[element] for element in my_array] )
print(result)

The result should be:

[1 2]

I don't know how efficient this is but seems like a very practical and straight-forward solution, no conversions or new classes needed :)

1 Comment

This is unrelated to the question. The keys in your dictionary are just strings ('key1', 'key2')

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.