The most straight forward Pythonic (i.e. uses good Python syntax) method is
results = [dict[value] for value in np_vec]
This needs refinement if dict might not have value.
Can I use a list comprehension on a list of dictionaries if a key is missing?
But perhaps you are hoping for something that passes as a vectorized numpy expression. The sticking point is that a dictionary will only access one key at a time
Another possibility is to use dict.keys() to get a list of keys, and use numpy methods to match np_vec with this list. No guarantee that this will be faster.
in1d doc
> in1d(a, b) is roughly equivalent to np.array([item in b for item in a]).
I'm thinking of something like (but details may be off)
keys = dict.keys()
values = dict.values()
mask = np.in1d(dict.keys(), np_vec)
result = values[mask]
Working code using arrays:
A dictionary with numeric keys, tuple values:
In [302]: adict={k:v for k,v in zip([0,1,2,3,4,5],[(0,1),(1,2),(2,3),(3,4),(4,5)])}
In [303]: adict
Out[303]: {0: (0, 1), 1: (1, 2), 2: (2, 3), 3: (3, 4), 4: (4, 5)}
Array of keys we want to fetch
In [304]: npvec=np.arange(4)
Lists from dictionary:
In [305]: keys=list(adict.keys())
In [308]: values=list(adict.values())
In [309]: values
Out[309]: [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5)]
mask - keys we want to pull
In [310]: mask=np.in1d(keys,npvec)
In [311]: mask
Out[311]: array([ True, True, True, True, False], dtype=bool)
To apply the mask in one step, we have to use an array; keys[mask] does not work:
In [313]: np.array(keys)[mask]
Out[313]: array([0, 1, 2, 3])
The same would work if values were simple numbers, but they are tuples.
In [314]: np.array(values)[mask]
Out[314]:
array([[0, 1],
[1, 2],
[2, 3],
[3, 4]])
We could turn that 2d array back into a list of tuples.
But to preserve tuples (or other general Python object values), we have to do something more complicated, e.g.
In [315]: varray=np.empty(len(values),dtype=object)
In [317]: for i in range(5):varray[i]=values[i]
In [318]: varray
Out[318]: array([(0, 1), (1, 2), (2, 3), (3, 4), (4, 5)], dtype=object)
Now we can apply the mask and get the right set of values.
In [319]: varray[mask]
Out[319]: array([(0, 1), (1, 2), (2, 3), (3, 4)], dtype=object)
Contrast that with the simple list comprehension solution:
In [321]: [adict[v] for v in npvec]
Out[321]: [(0, 1), (1, 2), (2, 3), (3, 4)]
Sometimes trying to be more Pythonic, err numpy-onic, just isn't worth the extra work.