Python dictionary: Get list of values for list of keys Python dictionary: Get list of values for list of keys python python

Python dictionary: Get list of values for list of keys


A list comprehension seems to be a good way to do this:

>>> [mydict[x] for x in mykeys][3, 1]


A couple of other ways than list-comp:

  • Build list and throw exception if key not found: map(mydict.__getitem__, mykeys)
  • Build list with None if key not found: map(mydict.get, mykeys)

Alternatively, using operator.itemgetter can return a tuple:

from operator import itemgettermyvalues = itemgetter(*mykeys)(mydict)# use `list(...)` if list is required

Note: in Python3, map returns an iterator rather than a list. Use list(map(...)) for a list.


A little speed comparison:

Python 2.7.11 |Anaconda 2.4.1 (64-bit)| (default, Dec  7 2015, 14:10:42) [MSC v.1500 64 bit (AMD64)] on win32In[1]: l = [0,1,2,3,2,3,1,2,0]In[2]: m = {0:10, 1:11, 2:12, 3:13}In[3]: %timeit [m[_] for _ in l]  # list comprehension1000000 loops, best of 3: 762 ns per loopIn[4]: %timeit map(lambda _: m[_], l)  # using 'map'1000000 loops, best of 3: 1.66 µs per loopIn[5]: %timeit list(m[_] for _ in l)  # a generator expression passed to a list constructor.1000000 loops, best of 3: 1.65 µs per loopIn[6]: %timeit map(m.__getitem__, l)The slowest run took 4.01 times longer than the fastest. This could mean that an intermediate result is being cached 1000000 loops, best of 3: 853 ns per loopIn[7]: %timeit map(m.get, l)1000000 loops, best of 3: 908 ns per loopIn[33]: from operator import itemgetterIn[34]: %timeit list(itemgetter(*l)(m))The slowest run took 9.26 times longer than the fastest. This could mean that an intermediate result is being cached 1000000 loops, best of 3: 739 ns per loop

So list comprehension and itemgetter are the fastest ways to do this.

UPDATE:For large random lists and maps I had a bit different results:

Python 2.7.11 |Anaconda 2.4.1 (64-bit)| (default, Dec  7 2015, 14:10:42) [MSC v.1500 64 bit (AMD64)] on win32In[2]: import numpy.random as nprndl = nprnd.randint(1000, size=10000)m = dict([(_, nprnd.rand()) for _ in range(1000)])from operator import itemgetterimport operatorf = operator.itemgetter(*l)%timeit f(m)%timeit list(itemgetter(*l)(m))%timeit [m[_] for _ in l]  # list comprehension%timeit map(m.__getitem__, l)%timeit list(m[_] for _ in l)  # a generator expression passed to a list constructor.%timeit map(m.get, l)%timeit map(lambda _: m[_], l)1000 loops, best of 3: 1.14 ms per loop1000 loops, best of 3: 1.68 ms per loop100 loops, best of 3: 2 ms per loop100 loops, best of 3: 2.05 ms per loop100 loops, best of 3: 2.19 ms per loop100 loops, best of 3: 2.53 ms per loop100 loops, best of 3: 2.9 ms per loop

So in this case the clear winner is f = operator.itemgetter(*l); f(m), and clear outsider: map(lambda _: m[_], l).

UPDATE for Python 3.6.4:

import numpy.random as nprndl = nprnd.randint(1000, size=10000)m = dict([(_, nprnd.rand()) for _ in range(1000)])from operator import itemgetterimport operatorf = operator.itemgetter(*l)%timeit f(m)%timeit list(itemgetter(*l)(m))%timeit [m[_] for _ in l]  # list comprehension%timeit list(map(m.__getitem__, l))%timeit list(m[_] for _ in l)  # a generator expression passed to a list constructor.%timeit list(map(m.get, l))%timeit list(map(lambda _: m[_], l)1.66 ms ± 74.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)2.1 ms ± 93.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)2.58 ms ± 88.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)2.36 ms ± 60.7 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)2.98 ms ± 142 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)2.7 ms ± 284 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)3.14 ms ± 62.6 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

So, results for Python 3.6.4 is almost the same.