Numba Dict(): find key of the minimum value in Dict

Assuming that I can pre define a numba typed dict() as:

testDict = numba.typed.Dict.empty(key_type=numba.types.unicode_type,value_type=numba.types.float64)

for ex:

testDict={'A1':1.1,'B2':1.2, 'C3':1.3, 'D4':1.4}

is it possible to find the key for the minimum value of the dict as in the python mode?

minkey=min(testDict, key=testDict.get)

I don’t know, but I’d guess not… what did you find when you tried it?

For the code below:

import numba
from numba import njit

@njit
def dict_test(A1,B2,C3,D4):
    testDict = numba.typed.Dict.empty(key_type=numba.types.unicode_type,value_type=numba.types.float64)
    testDict={'A1':A1,'B2':B2, 'C3':C3, 'D4':D4}
    minkey=min(testDict, key=testDict.get)
    return minkey


print(dict_test(1.5,1.7,1.3,1.4))

The error is:

Traceback (most recent call last):
  File "/home/user/tests/numba-dict-test.py", line 12, in <module>
    print(dict_test(1.5,1.7,1.3,1.4))
  File "/home/user/miniconda3/lib/python3.10/site-packages/numba/core/dispatcher.py", line 468, in _compile_for_args
    error_rewrite(e, 'typing')
  File "/home/user/miniconda3/lib/python3.10/site-packages/numba/core/dispatcher.py", line 409, in error_rewrite
    raise e.with_traceback(None)
numba.core.errors.TypingError: Failed in nopython mode pipeline (step: nopython frontend)
No implementation of function Function(<built-in function min>) found for signature:
 
 >>> min(DictType[unicode_type,float64]<iv=None>, key=BoundFunction((<class 'numba.core.types.containers.DictType'>, 'get') for DictType[unicode_type,float64]<iv=None>))
 
There are 6 candidate implementations:
  - Of which 2 did not match due to:
  Overload in function 'MinMaxBase.generic': File: numba/core/typing/builtins.py: Line 888.
    With argument(s): '(DictType[unicode_type,float64]<iv=None>, key=BoundFunction((<class 'numba.core.types.containers.DictType'>, 'get') for DictType[unicode_type,float64]<iv=None>))':
   Rejected as the implementation raised a specific error:
     AssertionError: 
  raised from /home/user/miniconda3/lib/python3.10/site-packages/numba/core/typing/builtins.py:892
  - Of which 2 did not match due to:
  Overload in function 'indval_min': File: numba/cpython/builtins.py: Line 548.
    With argument(s): '(DictType[unicode_type,float64]<iv=None>, key=BoundFunction((<class 'numba.core.types.containers.DictType'>, 'get') for DictType[unicode_type,float64]<iv=None>))':
   Rejected as the implementation raised a specific error:
     TypingError: missing a required argument: 'indval2'
  raised from /home/user/miniconda3/lib/python3.10/site-packages/numba/core/typing/templates.py:791
  - Of which 2 did not match due to:
  Overload in function 'iterable_min': File: numba/cpython/builtins.py: Line 623.
    With argument(s): '(DictType[unicode_type,float64]<iv=None>, key=BoundFunction((<class 'numba.core.types.containers.DictType'>, 'get') for DictType[unicode_type,float64]<iv=None>))':
   Rejected as the implementation raised a specific error:
     TypingError: got an unexpected keyword argument 'key'
  raised from /home/user/miniconda3/lib/python3.10/site-packages/numba/core/typing/templates.py:791

During: resolving callee type: Function(<built-in function min>)
During: typing of call at /home/user/tests/numba-dict-test.py (8)


File "numba-dict-test.py", line 8:
def dict_test(A1,B2,C3,D4):
    <source elided>
    testDict={'A1':A1,'B2':B2, 'C3':C3, 'D4':D4}
    minkey=min(testDict, key=testDict.get)
    ^

That’s not terribly surprising… looks like the kwarg variant isn’t implemented even though ‘min’ is a supported function

If you’re interested in an alternative, something like this does work.

return sorted([(val, key) for key, val in testDict.items()])[0][1]

Thanks! A much simpler solution than explicit looping! In my case testDict() is confined to four key-value pairs so this step is much faster and succinct.