Getting a list of values from a list of dicts
I have a list of dicts like this:
[{'value': 'apple', 'blah': 2},
{'value': 'banana', 'blah': 3} ,
{'value': 'cars',开发者_如何学Go 'blah': 4}]
I want ['apple', 'banana', 'cars']
Whats the best way to do this?
Assuming every dict has a value
key, you can write (assuming your list is named l
)
[d['value'] for d in l]
If value
might be missing, you can use
[d['value'] for d in l if 'value' in d]
Here's another way to do it using map() and lambda functions:
>>> map(lambda d: d['value'], l)
where l is the list. I see this way "sexiest", but I would do it using the list comprehension.
Update: In case that 'value' might be missing as a key use:
>>> map(lambda d: d.get('value', 'default value'), l)
Update: I'm also not a big fan of lambdas, I prefer to name things... this is how I would do it with that in mind:
>>> import operator
>>> get_value = operator.itemgetter('value')
>>> map(get_value, l)
I would even go further and create a sole function that explicitly says what I want to achieve:
>>> import operator, functools
>>> get_value = operator.itemgetter('value')
>>> get_values = functools.partial(map, get_value)
>>> get_values(l)
... [<list of values>]
With Python 3, since map
returns an iterator, use list
to return a list, e.g. list(map(operator.itemgetter('value'), l))
.
[x['value'] for x in list_of_dicts]
For a very simple case like this, a comprehension, as in Ismail Badawi's answer is definitely the way to go.
But when things get more complicated, and you need to start writing multi-clause or nested comprehensions with complex expressions in them, it's worth looking into other alternatives. There are a few different (quasi-)standard ways to specify XPath-style searches on nested dict-and-list structures, such as JSONPath, DPath, and KVC. And there are nice libraries on PyPI for them.
Here's an example with the library named dpath
, showing how it can simplify something just a bit more complicated:
>>> dd = {
... 'fruits': [{'value': 'apple', 'blah': 2}, {'value': 'banana', 'blah': 3}],
... 'vehicles': [{'value': 'cars', 'blah':4}]}
>>> {key: [{'value': d['value']} for d in value] for key, value in dd.items()}
{'fruits': [{'value': 'apple'}, {'value': 'banana'}],
'vehicles': [{'value': 'cars'}]}
>>> dpath.util.search(dd, '*/*/value')
{'fruits': [{'value': 'apple'}, {'value': 'banana'}],
'vehicles': [{'value': 'cars'}]}
Or, using jsonpath-ng
:
>>> [d['value'] for key, value in dd.items() for d in value]
['apple', 'banana', 'cars']
>>> [m.value for m in jsonpath_ng.parse('*.[*].value').find(dd)]
['apple', 'banana', 'cars']
This one may not look quite as simple at first glance, because find
returns match objects, which include all kinds of things besides just the matched value, such as a path directly to each item. But for more complex expressions, being able to specify a path like '*.[*].value'
instead of a comprehension clause for each *
can make a big difference. Plus, JSONPath is a language-agnostic specification, and there are even online testers that can be very handy for debugging.
I think as simple as below would give you what you are looking for.
In[5]: ll = [{'value': 'apple', 'blah': 2}, {'value': 'banana', 'blah': 3} , {'value': 'cars', 'blah':4}]
In[6]: ld = [d.get('value', None) for d in ll]
In[7]: ld
Out[7]: ['apple', 'banana', 'cars']
You can do this with a combination of map
and lambda
as well but list comprehension looks more elegant and pythonic.
For a smaller input list comprehension is way to go but if the input is really big then i guess generators are the ideal way.
In[11]: gd = (d.get('value', None) for d in ll)
In[12]: gd
Out[12]: <generator object <genexpr> at 0x7f5774568b10>
In[13]: '-'.join(gd)
Out[13]: 'apple-banana-cars'
Here is a comparison of all possible solutions for bigger input
In[2]: l = [{'value': 'apple', 'blah': 2}, {'value': 'banana', 'blah': 3} , {'value': 'cars', 'blah':4}] * 9000000
In[3]: def gen_version():
...: for i in l:
...: yield i.get('value', None)
...:
In[4]: def list_comp_verison():
...: return [i.get('value', None) for i in l]
...:
In[5]: def list_verison():
...: ll = []
...: for i in l:
...: ll.append(i.get('value', None))
...: return ll
In[10]: def map_lambda_version():
...: m = map(lambda i:i.get('value', None), l)
...: return m
...:
In[11]: %timeit gen_version()
172 ns ± 0.393 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
In[12]: %timeit map_lambda_version()
203 ns ± 2.31 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
In[13]: %timeit list_comp_verison()
1.61 s ± 20.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In[14]: %timeit list_verison()
2.29 s ± 4.58 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
As you can see, generators are a better solution in comparison to the others, map is also slower compared to generator for reason I will leave up to OP to figure out.
Using list comprehension
input:
d = [{'value': 'apple', 'blah': 2}, {'value': 'banana', 'blah': 3}, {'value': 'cars', 'blah': 4}]
values = [i['value'] for i in d]
print(values)
Output:
['apple', 'banana', 'cars']
Follow the example --
songs = [
{"title": "happy birthday", "playcount": 4},
{"title": "AC/DC", "playcount": 2},
{"title": "Billie Jean", "playcount": 6},
{"title": "Human Touch", "playcount": 3}
]
print("===========================")
print(f'Songs --> {songs} \n')
title = list(map(lambda x : x['title'], songs))
print(f'Print Title --> {title}')
playcount = list(map(lambda x : x['playcount'], songs))
print(f'Print Playcount --> {playcount}')
print (f'Print Sorted playcount --> {sorted(playcount)}')
# Aliter -
print(sorted(list(map(lambda x: x['playcount'],songs))))
Get key values from list of dictionaries in python?
- Get key values from list of dictionaries in python?
Ex:
data =
[{'obj1':[{'cpu_percentage':'15%','ram':3,'memory_percentage':'66%'}]},
{'obj2': [{'cpu_percentage':'0','ram':4,'memory_percentage':'35%'}]}]
for d in data:
for key,value in d.items():
z ={key: {'cpu_percentage': d['cpu_percentage'],'memory_percentage': d['memory_percentage']} for d in value}
print(z)
Output:
{'obj1': {'cpu_percentage': '15%', 'memory_percentage': '66%'}}
{'obj2': {'cpu_percentage': '0', 'memory_percentage': '35%'}}
Please try out this one.
d =[{'value': 'apple', 'blah': 2}, {'value': 'banana', 'blah': 3} , {'value':
'cars', 'blah': 4}]
b=d[0]['value']
c=d[1]['value']
d=d[2]['value']
new_list=[b,c,d]
print(new_list)
Output:
['apple', 'banana', 'cars']
A very simple way to do it is:
list1=['']
j=0
for i in com_list:
if j==0:
list1[0]=(i['value'])
else:
list1.append(i['value'])
j+=1
Output:
['apple', 'banana', 'cars']
精彩评论