5

For example:

persons = [{'id': 1, 'name': 'john'}, {'id': 2, 'name': 'mary'}, {'id': 3, 'name': 'tom'}]

I want to get two lists from it:

ids = [1, 2, 3]
names = ['john', 'mary', 'tom']

What I did:

names = [d['name'] for d in persons]
ids = [d['id'] for d in persons]

Is there a better way to do it?

marlon
  • 6,029
  • 8
  • 42
  • 76

5 Answers5

3

What you did works fine. Another way to handle this (not necessarily better, depending on your needs) is to store your data in a more efficient dictionary and pull the names/ids out of it when you need them:

>>> persons = [{'id': 1, 'name': 'john'}, {'id': 2, 'name': 'mary'}, {'id': 3, 'name': 'tom'}]
>>> p2 = {x['id']: x['name'] for x in persons}
>>> p2
{1: 'john', 2: 'mary', 3: 'tom'}

>>> list(p2.keys())
[1, 2, 3]

>>> list(p2.values())
['john', 'mary', 'tom']
Woodford
  • 3,746
  • 1
  • 15
  • 29
3

I'd stick with using list comprehension or use @Woodford technique

ids,name = [dcts['id'] for dcts in persons],[dcts['name'] for dcts in persons]

output

[1, 2, 3] 
['john', 'mary', 'tom']
Buddy Bob
  • 5,829
  • 1
  • 13
  • 44
2

An alternative, inspired by this question, is

ids, names = zip(*map(lambda x: x.values(), persons))

that return tuples. If you need lists

ids, names = map(list, zip(*map(lambda x: x.values(), persons)))

It is a little bit slower on my laptop using python3.9 than the accepted answer but it might be useful.

Andrea Di Iura
  • 467
  • 5
  • 11
1

You can do it with pandas in a vectorized fashion:

import pandas as pd
persons = [{'id': 1, 'name': 'john'}, {'id': 2, 'name': 'mary'}, {'id': 3, 'name': 'tom'}]

df = pd.DataFrame(persons)
id_list = df.id.tolist() #[1, 2, 3]
name_list = df.name.tolist() #['john', 'mary', 'tom']
pakpe
  • 5,391
  • 2
  • 8
  • 23
0

It sounds like you're trying to iterate through the values of your list while unpacking your dictionaries:

persons = [{'id': 1, 'name': 'john'}, {'id': 2, 'name': 'mary'}, {'id': 3, 'name': 'tom'}]


for x in persons:
    id, name = x.values()
    ids.append(id)
    names.append(name)
Yaakov Bressler
  • 9,056
  • 2
  • 45
  • 69