Eric B
Eric B

Reputation: 1675

Extracting dictionary items embedded in a list

Let's say I have the following list of dict

t = [{'a': 1.0, 'b': 2.0},
     {'a': 3.0, 'b': 4.0},
     {'a': 5.0, 'b': 6.0},
     {'a': 7.0, 'b': 9.0},
     {'a': 9.0, 'b': 0.0}]

Is there an efficient way to extract all the values contained in the dictionaries with a dictionary key value of a?

So far I have come up with the following solution

x = []
for j in t:
    x.append(j['a'])

However, I don't like to loop over items, and was looking at a nicer way to achieve this goal.

Upvotes: 9

Views: 34594

Answers (3)

Ajax1234
Ajax1234

Reputation: 71451

You can use list comprehension:

t = [{'a': 1.0, 'b': 2.0},
 {'a': 3.0, 'b': 4.0},
 {'a': 5.0, 'b': 6.0},
 {'a': 7.0, 'b': 9.0},
 {'a': 9.0, 'b': 0.0}]
new_list = [i["a"] for i in t]

Output:

[1.0, 3.0, 5.0, 7.0, 9.0]

Since this solution uses a for-loop, you can use map instead:

x = list(map(lambda x: x["a"], t))

Output:

[1.0, 3.0, 5.0, 7.0, 9.0]

Performance-wise, you prefer to use list-comprehension solution rather the map one.

>>> timeit('new_list = [i["a"] for i in t]', setup='from __main__ import t', number=10000000)
4.318223718035199

>>> timeit('x = list(map(lambda x: x["a"], t))', setup='from __main__ import t', number=10000000)
16.243124993163093


def temp(p):
    return p['a']

>>> timeit('x = list(map(temp, t))', setup='from __main__ import t, temp', number=10000000)
16.048683850689343

There is a slightly difference when using a lambda or a regular function; however, the comprehension execution takes 1/4 of the time.

Upvotes: 23

mhawke
mhawke

Reputation: 87064

Use a list comprehension as suggested in Ajax1234'a answer, or even a generator expression if that would benefit your use case:

t = [{'a': 1.0, 'b': 2.0}, {'a': 3.0, 'b': 4.0}, {'a': 5.0, 'b': 6.0}, {'a': 7.0, 'b': 9.0}, {'a': 9.0, 'b': 0.0}]
x = (item["a"] for item in t)
print(x)

Output:

<generator object <genexpr> at 0x7f0027def550>

The generator has the advantage of not executing or consuming memory until a value is needed. Use next() to take the next item from the generator, or iterate over it with a for loop.

>>> next(x)
1.0
>>> next(x)
3.0
>>> for n in x:
...     print(n)
5.0
7.0
9.0

An alternative, albeit a expensive one, is to use pandas:

import pandas as pd

x = pd.DataFrame(t)['a'].tolist()
print(x)

Output:

[1.0, 3.0, 5.0, 7.0, 9.0]

Upvotes: 0

Don
Don

Reputation: 17606

You can use itemgetter:

from operator import itemgetter

t = [{'a': 1.0, 'b': 2.0},
     {'a': 3.0, 'b': 4.0},
     {'a': 5.0, 'b': 6.0},
     {'a': 7.0, 'b': 9.0},
     {'a': 9.0, 'b': 0.0}]

print map(itemgetter('a'), t)

result:

[1.0, 3.0, 5.0, 7.0, 9.0]

Upvotes: 2

Related Questions