0

I have a dictionary composed of arrays of unequal length that looks like the following:

mydict = {'A': array([ 1,  5,  6, 10, 13, 17, 20, 22]), 'B': array([ 3,  8,  9, 15, 16]), 'C': array([ 0,  2,  4,  7, 11, 12, 14])}

I'm looking to retrieve the key for a given number (e.g. key for 22 being 'A'), but I'm guessing it's the multi-array structure of this dict that is producing an error when using previously posted solutions:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

Is there a straightforward way to connect the value to the key with this dict without transforming the array structure? Ultimately I'm trying to add the key of a value to a row with other associated data for export.

What I attempted based on previous answers:

res = dict((v, k) for k, v in mydict.items())
print(res[10])

I want it to print 'A' but it produces

TypeError: unhashable type: 'numpy.ndarray'

mkrieger1
  • 19,194
  • 5
  • 54
  • 65
  • 1
    Have you tried using `[k for k in mydict if 22 in mydict[k]]`? The other solution you linked to doesn't seem to apply here, because you are not searching for an array but for a value *in* an array. – mkrieger1 Feb 13 '23 at 14:24
  • 1
    For the second attempt, see e.g. https://stackoverflow.com/questions/35945473/how-to-reverse-a-dictionary-whose-values-are-lists-in-python – mkrieger1 Feb 13 '23 at 14:31
  • You get the 'ambiguity' error when doing something like `if 22==arr`. in general `==` tests on an array is tricky. And arrays can't be dict keys. – hpaulj Feb 13 '23 at 15:43

2 Answers2

1

Make a reversed dictionary you can use as a lookup (NB: this assumes you have no duplicates in your arrays - if you do they will be overwritten)

from numpy import array

mydict = {'A': array([ 1,  5,  6, 10, 13, 17, 20, 22]), 
          'B': array([ 3,  8,  9, 15, 16]), 
          'C': array([ 0,  2,  4,  7, 11, 12, 14])}
rev_dct = {val: k for k, v in mydict.items() for val in v}
print(rev_dct[22])
>>> 'A'
oskros
  • 3,101
  • 2
  • 9
  • 28
1

If you are doing it once, you may want to just do a filter:

from numpy import array

mydict = {'A': array([ 1,  5,  6, 10, 13, 17, 20, 22]), 'B': array([ 3,  8,  9, 15, 16]), 'C': array([ 0,  2,  4,  7, 11, 12, 14])}

res = list(filter(lambda k: 20 in mydict[k], mydict))

print(res)

This sets res to:

['A']

If the values only occur in one array (i.e. you only expect one key to hold a given value) then you can do a reverse/bidirectional dictionary as mentioned by oskros.

Tom McLean
  • 5,583
  • 1
  • 11
  • 36