I have a dictionary:
d = {'a':1, 'b':2, 'c':3, 'd':4}
Then I have a list of keys:
l = ['a', 'b', 'z']
My desired result is:
[1, 2, None]
What I'm doing so far is:
[d.get(k) for k in l]
Is there a faster way? Perhaps without for
?
As you can see from the Output, the multiple keys have the same name in a dictionary. Here we can see how to get multiple keys in a Python dictionary.
In this example, if you want to get multiple keys-values then you need to associate an object with each key as a value. In the given dict the keys are strings and with every single key, we assign a list of numbers as a value.
keys () method in Python Dictionary, returns a view object that displays a list of all the keys in the dictionary in order of insertion. Parameters: There are no parameters. Returns: A view object is returned that displays all the keys. This view object changes according to the changes in the dictionary.
A dictionary can be defined as a set of key:value pairs where the keys are unique for a given dictionary. What is a Multidict? Multidict is a dictionary where several values are mapped to one key. Here, key ‘ d’ has 2 elements and key ‘ e’ has 3 elements. Think that you have a tuple containing three vegetables and five fruits.
You could use:
>>> list(map(d.get, l))
[1, 2, None]
It has two advantages:
d.get
lookup only once - not each iterationdict.get
is implemented in C and map
is implemented in C it can avoid the Python layer in the function call (roughly speaking the details are a bit more complicated).As for timings (performed on Python 3.6 in a Jupyter notebook):
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)
Note that this is actually slower in this case! That's because for short iterables the map
and list
overhead dominate. So if you want it faster on short iterables stick with your approach.
With longer l
you see that list(map(...))
eventually becomes faster:
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 that's still "just" a factor of 2 faster.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With