mshabeeb mshabeeb - 12 days ago 9
Python Question

Getting all values for a certain key in a python list of dictionaries

I have a list in Python which contains a "nested" dictionary in it. So my list looks like follows:

List = [{'entry' : {'Name' : 'Smith', 'Age' : 25}}, {'entry' : {'Name' : 'Mary', 'Age' : 28}}]


I would like to return all the values of the key 'Name' from my list without using a loop. So if I use a loop it works since this works for single entries of the list. For example:
List[0]['entry']['Name']
works and returns 'Smith'. However, I need something like
List[:]['entry']['Name']
which should return a List with the entries 'Smith' and 'Mary' in it. Is this possible?

Answer

I had posted the reduce option as a curiosity, but since the answer was accepted, I decided to post the timeit results to compare the performance with the other answers on this ticket.

from timeit import timeit
import functools

def test1(the_list):

    return reduce(lambda l, src: l.append(src['entry']['Name']) or l, the_list, [])

def test1_py3(the_list):

    return functools.reduce(lambda l, src: l.append(src['entry']['Name']) or l, the_list, [])

def test2(the_list):

    return map(lambda d: d['entry']['Name'], the_list)

def test3(the_list):

    return [d['entry']['Name'] for d in the_list]


the_list = [{'entry' : {'Name' : 'Smith', 'Age' : 25}}, {'entry' : {'Name' : 'Mary', 'Age' : 28}}]
reps = 1000
# Compare timings
print('test1:  ', timeit('c(the_list)', 'from __main__ import test1_py3 as c, the_list', number=reps))
print('test2:  ', timeit('c(the_list)', 'from __main__ import test2 as c, the_list', number=reps))
print('test3:  ', timeit('c(the_list)', 'from __main__ import test3 as c, the_list', number=reps))

Results

Py 2
reduce:               0.0013170242309570312
map:                  0.0008721351623535156
list comprehension:   0.00037407875061035156

Py 3
functools.reduce:     0.001067782985046506
map:                  0.0005585199978668243
list comprehension:   0.0007099689973983914