Reputation: 1229
I have a function which iterates over a list of dicts, returning specified key-value pairs into a new list of dicts:
data = [
{'user': {'login': 'foo1', 'id': 'bar2'}, 'body': 'Im not sure', 'other_field': 'value'},
{'user': {'login': 'foo2', 'id': 'bar3'}, 'body': 'Im still not sure', 'other_field': 'value'},
]
filtered_list = []
keys = ['user','body']
for i in data:
filt_dict = dict((k, i[k]) for k in keys if k in i)
filtered_list.append(filt_dict)
The user
key contains a sub-key called login
; how can this be added to the keys argument list, instead of the key user
?
Sample output:
filtered_list = [
{'login': 'foo1', 'body': 'Im not sure'},
{'login': 'foo2', 'body': 'Im still not sure'},
]
Upvotes: 3
Views: 323
Reputation: 16505
If you are certain, that all elements (dicts) in the list will have the keys you specified, then a quick solution could be this:
filtered_list = [
{
'login': elem['user']['login'],
'body': elem['body'],
}
for elem in data]
This has no error handling for missing keys.
Upvotes: 1
Reputation: 78700
How about this? Assumes your chain of keys actually exists in the dicts you are iterating.
Setup
>>> from functools import reduce
>>> data = [{'user': {'login': 'foo1', 'id': 'bar2'}, 'body': 'Im not sure', 'other_field': 'value'},
... {'user': {'login': 'foo2', 'id': 'bar3'}, 'body': 'Im still not sure', 'other_field': 'value'}]
>>> keys = [('user', 'login'), ('body',)]
Solution
>>> [{ks[-1]: reduce(dict.get, ks, d) for ks in keys} for d in data]
[{'body': 'Im not sure', 'login': 'foo1'}, {'body': 'Im still not sure', 'login': 'foo2'}]
Upvotes: 5