从字典列表中获取值列表

问题:从字典列表中获取值列表

我有这样的字典列表:

[{'value': 'apple', 'blah': 2}, 
 {'value': 'banana', 'blah': 3} , 
 {'value': 'cars', 'blah': 4}]

我想要 ['apple', 'banana', 'cars']

最好的方法是什么?

I have a list of dicts like this:

[{'value': 'apple', 'blah': 2}, 
 {'value': 'banana', 'blah': 3} , 
 {'value': 'cars', 'blah': 4}]

I want ['apple', 'banana', 'cars']

Whats the best way to do this?


回答 0

假设每个字典都有一个value键,您可以编写(假设您的列表名为l

[d['value'] for d in l]

如果value可能丢失,可以使用

[d['value'] for d in l if 'value' in d]

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]

回答 1

这是使用map()和lambda函数实现此目标的另一种方法:

>>> map(lambda d: d['value'], l)

其中l是列表。我认为这种方式“最性感”,但是我会使用列表理解来做到这一点。

更新:如果可能缺少“值”作为关键用法:

>>> map(lambda d: d.get('value', 'default value'), l)

更新:我也不是lambda的忠实拥护者,我更喜欢命名……这是我会想到的:

>>> import operator
>>> map(operator.itemgetter('value'), l)

我什至会更进一步,创建一个唯一的函数来明确说明我要实现的目标:

>>> import operator, functools
>>> get_values = functools.partial(map, operator.itemgetter('value'))
>>> get_values(l)
... [<list of values>]

在Python 3中,由于map返回迭代器,因此可list用于返回列表,例如list(map(operator.itemgetter('value'), l))

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
>>> map(operator.itemgetter('value'), l)

I would even go further and create a sole function that explicitly says what I want to achieve:

>>> import operator, functools
>>> get_values = functools.partial(map, operator.itemgetter('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)).


回答 2

[x['value'] for x in list_of_dicts]
[x['value'] for x in list_of_dicts]

回答 3

对于像这样的非常简单的情况,如Ismail Badawi的答案中所述的理解无疑是必经之路。

但是,当事情变得更加复杂,并且您需要开始编写包含复杂表达式的多子句或嵌套式理解时,值得探索其他替代方法。在嵌套的字典和列表结构(例如JSONPath,DPath和KVC)上指定XPath样式搜索有几种不同的(准)标准方法。而且在PyPI上有适合他们的漂亮库。

这是一个名为的库的示例dpath,显示了如何简化一些复杂的事情:

>>> 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'}]}

或者,使用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']

乍一看,这可能看起来并不那么简单,因为find返回匹配对象,除了匹配的值外,还包括所有其他内容,例如直接指向每个项目的路径。但是对于更复杂的表达式,能够'*.[*].value'为每个表达式指定类似的路径而不是comprehension子句*会产生很大的不同。另外,JSONPath是与语言无关的规范,甚至还有在线测试人员也可以非常方便地进行调试。

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.


回答 4

根据例子 –

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))))

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))))

回答 5

我认为如下所示的简单操作将为您提供所需的内容。

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']

您也可以结合使用map和来做到这一点,lambda但是列表理解看起来更加优雅和Pythonic。

对于较小的输入列表,理解是一种方法,但是如果输入确实很大,那么我认为生成器是理想的方法。

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'

这是所有可能的解决方案的比较,以获取更大的输入

 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)

如您所见,与其他生成器相比,生成器是一种更好的解决方案,与生成器相比,map的运行速度也较慢,原因是我将不去考虑OP。

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.


回答 6

从python词典列表中获取键值?

  1. 从python词典列表中获取键值?

例如:

data = 
[{'obj1':[{'cpu_percentage':'15%','ram':3,'memory_percentage':'66%'}]},
{'obj2': [{'cpu_percentage':'0','ram':4,'memory_percentage':'35%'}]}]

对于数据中的d:

  for key,value in d.items(): 

      z ={key: {'cpu_percentage': d['cpu_percentage'],'memory_percentage': d['memory_percentage']} for d in value} 
      print(z)

输出:

{'obj1': {'cpu_percentage': '15%', 'memory_percentage': '66%'}}
{'obj2': {'cpu_percentage': '0', 'memory_percentage': '35%'}}

Get key values from list of dictionaries in python?

  1. 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%'}}

回答 7

请尝试这个。

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)

输出:

['apple', 'banana', 'cars']

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']

回答 8

一个非常简单的方法是:

list1=['']
j=0
for i in com_list:
    if j==0:
        list1[0]=(i['value'])
    else:
        list1.append(i['value'])
    j+=1

输出:

[“苹果”,“香蕉”,“汽车”]

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’]