Reputation: 12264
I have a list of dicts, each dict has a data
key. Each data key contains a bunch of attributes about a person, none of those attributes are mandatory:
persons = [
{"Name": "John", "data": {"Age": 23, "Gender": "Male"}},
{"Name": "Jane", "data": {"Age": 22, "Gender": "Female"}},
{"Name": "Harry", "data": {"Age": 22}},
{"Name": "Hermione", "data": {"Gender": "Female"}},
]
What I'd like to do is extract a distinct list of the Age values. I've done it like this:
ages = set()
persondatas = [person['data'] for person in persons]
for persondata in persondatas:
if 'Age' in persondata:
ages.add(persondata['Age'])
ages
which returns:
{22, 23}
which is exactly what I want but I'm thinking there must be a better, neater, way than looping over a list that I obtained using a list comprehension. Can I do the required work inside a list comprehension perhaps? My first aborted attempt went like this:
[person['data']['Age'] for person in l]
which failed:
KeyError: 'Age'
There must be a better way but I've fiddled around and can't work it out. Can anyone help?
Upvotes: 2
Views: 58
Reputation: 164673
One solution is a list comprehension combined with filter.
set(filter(None, [p['data'].get('Age') for p in persons]))
Upvotes: 0
Reputation: 6206
Try this:
ages = set([person["data"]["Age"] for person in persons if "Age" in person["data"]])
Upvotes: 1
Reputation: 59974
You could add a conditional into your list comprehension - knock out both operations with one loop.
>>> {person['data']['Age'] for person in persons if 'Age' in person['data']}
set([22, 23])
Notice how I use curly braces ({}
), instead of square brackets ([]
), to denote a set comprehension.
Upvotes: 4