从字典列表中获取值列表


198

我有这样的字典列表:

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

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

最好的方法是什么?

Answers:


347

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

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

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

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

8
为了处理键的缺失值,也可以使用d.get(“ key_to_lookup”,“ alternate_value”)。然后,它看起来像:[d in l中的d.get('value','alt')]。如果没有值作为键,它将仅返回“ alt”。
abhinav

感谢您的解决方案
Ajay Kumar

这种“神奇”之称的列表理解docs.python.org/3/tutorial/...
威廉·阿迪拉

救命!很久以来,我一直在尝试/搜索sqlalchemy对象。现在它的工作就像[d.value for d in l]谢谢您一样:)
krupesh Anadkat

37

这是使用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))


1
列表理解在这里更有意义。
Mike Graham

4
如果您要使用第一个map,请使用operator.itemgetter('value'),而不要使用lambda
2011年

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

或[dict_list中d的[d.getkey('value')for d]
rplnt

2
@rpInt嗯,没有getkey..这样的东西d.get('value')吗?这与@isbadawi的第二列表理解相同,而不是Michal的。
2011年

3
是的,对不起,我的意思是。我的意思是,如果缺少键,它不会引发异常。但是@isbadawi的解决方案更好,因为缺少密钥时get()将提供None(或我们指定的默认值)。
rplnt 2011年

5

对于像这样的非常简单的情况,如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是与语言无关的规范,甚至还有在线测试人员也可以非常方便地进行调试。


2

根据例子 -

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

1

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

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。


1

从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%'}}

0

请尝试这个。

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

-3

一个非常简单的方法是:

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

输出:

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.