You can use:
>>> list(map(d.get, l)) [1, 2, None]
It has two advantages:
- It searches
d.get only once - not every iteration - Only CPython: since
dict.get implemented in C and map implemented in C, it can avoid the Python layer in the function call (roughly speaking, the details are a bit more complicated).
As for the timings (performed on Python 3.6 in a Jupyter laptop):
d = {'a':1, 'b':2, 'c':3, 'd':4} l = ['a', 'b', 'z'] %timeit list(map(d.get, l)) 594 ns ± 41.7 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) %timeit [d.get(k) for k in l] 508 ns ± 17.1 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
Please note that in this case it is actually slower! This is because the map and list add-ons dominate for short iterations. Therefore, if you want it to be faster in short iterations, stick to your approach.
With a longer l you will see that list(map(...)) will become faster over time:
d = {'a':1, 'b':2, 'c':3, 'd':4} l = [random.choice(string.ascii_lowercase) for _ in range(10000)] %timeit list(map(d.get, l)) 663 µs ± 64.6 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) %timeit [d.get(k) for k in l] 1.13 ms ± 7.55 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
However, it is still "just" 2 times faster.
source share