Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

is there a faster way to get multiple keys from dictionary?

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?

like image 999
Ezer K Avatar asked Mar 29 '18 12:03

Ezer K


People also ask

Can multiple keys have the same name in a Python dictionary?

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.

How to get multiple keys-values from a dict in Python?

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.

How to get all keys of a dictionary in Python?

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.

What is the difference between dictionary and multidict?

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.


1 Answers

You could use:

>>> list(map(d.get, l))
[1, 2, None]

It has two advantages:

  • It performs the d.get lookup only once - not each iteration
  • Only CPython: Because dict.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.

like image 61
MSeifert Avatar answered Nov 15 '22 22:11

MSeifert