How to get multiple dictionary values?
Question:
I have a dictionary in Python, and what I want to do is get some values from it as a list, but I don’t know if this is supported by the implementation.
myDictionary.get('firstKey') # works fine
myDictionary.get('firstKey','secondKey')
# gives me a KeyError -> OK, get is not defined for multiple keys
myDictionary['firstKey','secondKey'] # doesn't work either
Is there any way I can achieve this? In my example it looks easy, but let’s say I have a dictionary of 20 entries, and I want to get 5 keys. Is there any other way than doing the following?
myDictionary.get('firstKey')
myDictionary.get('secondKey')
myDictionary.get('thirdKey')
myDictionary.get('fourthKey')
myDictionary.get('fifthKey')
Answers:
Use a for
loop:
keys = ['firstKey', 'secondKey', 'thirdKey']
for key in keys:
myDictionary.get(key)
or a list comprehension:
[myDictionary.get(key) for key in keys]
There already exists a function for this:
from operator import itemgetter
my_dict = {x: x**2 for x in range(10)}
itemgetter(1, 3, 2, 5)(my_dict)
#>>> (1, 9, 4, 25)
itemgetter
will return a tuple if more than one argument is passed. To pass a list to itemgetter
, use
itemgetter(*wanted_keys)(my_dict)
Keep in mind that itemgetter
does not wrap its output in a tuple when only one key is requested, and does not support zero keys being requested.
You can use At
from pydash:
from pydash import at
my_dict = {'a': 1, 'b': 2, 'c': 3}
my_list = at(my_dict, 'a', 'b')
my_list == [1, 2]
If the fallback keys are not too many you can do something like this
value = my_dict.get('first_key') or my_dict.get('second_key')
I’d suggest the very useful map
function, which allows a function to operate element-wise on a list:
mydictionary = {'a': 'apple', 'b': 'bear', 'c': 'castle'}
keys = ['b', 'c']
values = list( map(mydictionary.get, keys) )
# values = ['bear', 'castle']
If you have pandas
installed you can turn it into a series with the keys as the index. So something like
import pandas as pd
s = pd.Series(my_dict)
s[['key1', 'key3', 'key2']]
As I see no similar answer here – it is worth pointing out that with the usage of a (list / generator) comprehension, you can unpack those multiple values and assign them to multiple variables in a single line of code:
first_val, second_val = (myDict.get(key) for key in [first_key, second_key])
I think list comprehension is one of the cleanest ways that doesn’t need any additional imports:
>>> d={"foo": 1, "bar": 2, "baz": 3}
>>> a = [d.get(k) for k in ["foo", "bar", "baz"]]
>>> a
[1, 2, 3]
Or if you want the values as individual variables then use multiple-assignment:
>>> a,b,c = [d.get(k) for k in ["foo", "bar", "baz"]]
>>> a,b,c
(1, 2, 3)
def get_all_values(nested_dictionary):
for key, value in nested_dictionary.items():
if type(value) is dict:
get_all_values(value)
else:
print(key, ":", value)
nested_dictionary = {'ResponseCode': 200, 'Data': {'256': {'StartDate': '2022-02-07', 'EndDate': '2022-02-27', 'IsStoreClose': False, 'StoreTypeMsg': 'Manual Processing Stopped', 'is_sync': False}}}
get_all_values(nested_dictionary)
def get_all_values(nested_dictionary):
for key, val in nested_dictionary.items():
data_list = []
if type(val) is dict:
for key1, val1 in val.items():
data_list.append(val1)
return data_list
If you want to retain the mapping of the values to the keys, you should use a dict comprehension instead:
{key: myDictionary[key] for key in [
'firstKey',
'secondKey',
'thirdKey',
'fourthKey',
'fifthKey'
]}
Slighlty different variation of list comprehension approach.
#doc
[dict[key] for key in (tuple_of_searched_keys)]
#example
my_dict = {x: x**2 for x in range(10)}
print([my_dict[key] for key in (8,9)])
%timeit
response of all the answers listed above. My apologies if missed some of the solutions, and I used my judgment to club similar answers. itemgetter
seems to be the winner to me. pydash
reports much lesser time but I don’t know why it ran lesser loops and don’t know if I can call it a fastest. Your thoughts?
from operator import itemgetter
my_dict = {x: x**2 for x in range(10)}
req_keys = [1, 3, 2, 5]
%timeit itemgetter(1, 3, 2, 5)(my_dict)
257 ns ± 4.61 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%timeit [my_dict.get(key) for key in req_keys]
604 ns ± 6.94 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%timeit list( map(my_dict.get, req_keys) )
529 ns ± 34.2 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
!pip install pydash
from pydash import at
%timeit at(my_dict, 1, 3, 2, 5)
22.2 µs ± 572 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
%timeit (my_dict.get(key) for key in req_keys)
308 ns ± 6.53 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
s = pd.Series(my_dict)
%timeit s[req_keys]
334 µs ± 58.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
I have a dictionary in Python, and what I want to do is get some values from it as a list, but I don’t know if this is supported by the implementation.
myDictionary.get('firstKey') # works fine
myDictionary.get('firstKey','secondKey')
# gives me a KeyError -> OK, get is not defined for multiple keys
myDictionary['firstKey','secondKey'] # doesn't work either
Is there any way I can achieve this? In my example it looks easy, but let’s say I have a dictionary of 20 entries, and I want to get 5 keys. Is there any other way than doing the following?
myDictionary.get('firstKey')
myDictionary.get('secondKey')
myDictionary.get('thirdKey')
myDictionary.get('fourthKey')
myDictionary.get('fifthKey')
Use a for
loop:
keys = ['firstKey', 'secondKey', 'thirdKey']
for key in keys:
myDictionary.get(key)
or a list comprehension:
[myDictionary.get(key) for key in keys]
There already exists a function for this:
from operator import itemgetter
my_dict = {x: x**2 for x in range(10)}
itemgetter(1, 3, 2, 5)(my_dict)
#>>> (1, 9, 4, 25)
itemgetter
will return a tuple if more than one argument is passed. To pass a list to itemgetter
, use
itemgetter(*wanted_keys)(my_dict)
Keep in mind that itemgetter
does not wrap its output in a tuple when only one key is requested, and does not support zero keys being requested.
You can use At
from pydash:
from pydash import at
my_dict = {'a': 1, 'b': 2, 'c': 3}
my_list = at(my_dict, 'a', 'b')
my_list == [1, 2]
If the fallback keys are not too many you can do something like this
value = my_dict.get('first_key') or my_dict.get('second_key')
I’d suggest the very useful map
function, which allows a function to operate element-wise on a list:
mydictionary = {'a': 'apple', 'b': 'bear', 'c': 'castle'}
keys = ['b', 'c']
values = list( map(mydictionary.get, keys) )
# values = ['bear', 'castle']
If you have pandas
installed you can turn it into a series with the keys as the index. So something like
import pandas as pd
s = pd.Series(my_dict)
s[['key1', 'key3', 'key2']]
As I see no similar answer here – it is worth pointing out that with the usage of a (list / generator) comprehension, you can unpack those multiple values and assign them to multiple variables in a single line of code:
first_val, second_val = (myDict.get(key) for key in [first_key, second_key])
I think list comprehension is one of the cleanest ways that doesn’t need any additional imports:
>>> d={"foo": 1, "bar": 2, "baz": 3}
>>> a = [d.get(k) for k in ["foo", "bar", "baz"]]
>>> a
[1, 2, 3]
Or if you want the values as individual variables then use multiple-assignment:
>>> a,b,c = [d.get(k) for k in ["foo", "bar", "baz"]]
>>> a,b,c
(1, 2, 3)
def get_all_values(nested_dictionary):
for key, value in nested_dictionary.items():
if type(value) is dict:
get_all_values(value)
else:
print(key, ":", value)
nested_dictionary = {'ResponseCode': 200, 'Data': {'256': {'StartDate': '2022-02-07', 'EndDate': '2022-02-27', 'IsStoreClose': False, 'StoreTypeMsg': 'Manual Processing Stopped', 'is_sync': False}}}
get_all_values(nested_dictionary)
def get_all_values(nested_dictionary):
for key, val in nested_dictionary.items():
data_list = []
if type(val) is dict:
for key1, val1 in val.items():
data_list.append(val1)
return data_list
If you want to retain the mapping of the values to the keys, you should use a dict comprehension instead:
{key: myDictionary[key] for key in [
'firstKey',
'secondKey',
'thirdKey',
'fourthKey',
'fifthKey'
]}
Slighlty different variation of list comprehension approach.
#doc
[dict[key] for key in (tuple_of_searched_keys)]
#example
my_dict = {x: x**2 for x in range(10)}
print([my_dict[key] for key in (8,9)])
%timeit
response of all the answers listed above. My apologies if missed some of the solutions, and I used my judgment to club similar answers. itemgetter
seems to be the winner to me. pydash
reports much lesser time but I don’t know why it ran lesser loops and don’t know if I can call it a fastest. Your thoughts?
from operator import itemgetter
my_dict = {x: x**2 for x in range(10)}
req_keys = [1, 3, 2, 5]
%timeit itemgetter(1, 3, 2, 5)(my_dict)
257 ns ± 4.61 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%timeit [my_dict.get(key) for key in req_keys]
604 ns ± 6.94 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%timeit list( map(my_dict.get, req_keys) )
529 ns ± 34.2 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
!pip install pydash
from pydash import at
%timeit at(my_dict, 1, 3, 2, 5)
22.2 µs ± 572 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
%timeit (my_dict.get(key) for key in req_keys)
308 ns ± 6.53 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
s = pd.Series(my_dict)
%timeit s[req_keys]
334 µs ± 58.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)