从字典列表中获取值列表

312

我有一个像这样的字典列表:

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

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

如何最好地完成这个任务?

10个回答

523

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

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

如果可能会缺失value,您可以使用

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

12
为了处理缺失的键值,可以使用d.get("key_to_lookup", "alternate_value")。那么,代码看起来将是这样的:[d.get('value', 'alt') for d in l]。如果键值不存在,它会简单地返回'alt'。 - abhinav
这种“魔法”被称为列表推导式 https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions - William Ardila
救命稻草!我一直在尝试/搜索SQLAlchemy对象的这个问题,现在它像这样工作:[d.value for d in l] 谢谢 :) - krupesh Anadkat
将会是 d['Value'] 而不是 d['value'] - Rafiq

60

这是另一种使用map()和lambda函数的方法:

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

其中l是列表。 我认为这种方法很“性感”,但我会使用列表推导式来实现。

更新: 如果'value'可能作为键缺失,请使用:

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

更新:我也不太喜欢使用lambda函数,我更喜欢为事物命名...... 根据这个想法,我会这样做:

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

我甚至会更进一步,创建一个单独的函数,明确表达我想要实现的目标:

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

使用Python 3时,由于map返回一个迭代器,请使用list将其转换为列表,例如:list(map(operator.itemgetter('value'), l))


2
列表推导式在这里更有意义。 - Mike Graham
5
如果您要使用第一个map,请使用operator.itemgetter('value')而不是lambda - agf

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

[d.getkey('value') for d in dict_list]: - rplnt
4
嗯,getkey 这个东西是不存在的...你是不是指 d.get('value')?那和 @isbadawi 的第二个列表推导式是一样的,跟 Michal 的不一样。 - agf
4
是的,抱歉,我原来的意思是使用get()方法。如果键不存在,它不会引发异常。但是@isbadawi的解决方案更好,因为get()方法会在键不存在时提供None(或我们指定的默认值)。 - rplnt

7
我认为以下简单的内容可以给您想要的结果。
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']

你可以使用maplambda的组合来实现,但是列表推导式看起来更加优雅和符合Python风格。 对于较小的输入,列表推导式是最好的选择,但如果输入非常大,则生成器是理想的方式。
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自行解决。


6
对于像这样非常简单的情况,像Ismail Badawi's answer中所述的列表推导式绝对是正确的选择。
但是当事情变得更加复杂,并且您需要开始编写具有复杂表达式的多子句或嵌套推导式时,值得研究其他替代方案。有几种不同的(准)标准方法可以在嵌套的字典和列表结构上指定类似XPath的搜索,例如JSONPath、DPath和KVC。而且,它们在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'这样的路径而不是为每个*编写一个推导子句,可以产生很大的差异。此外,JSONPath是一种与语言无关的规范,甚至有在线测试工具可以非常方便地进行调试。

6

使用列表推导式

输入:

d = [{'value': 'apple', 'blah': 2}, {'value': 'banana', 'blah': 3}, {'value': 'cars', 'blah': 4}]
    
        
values = [i['value'] for i in d]

print(values)

输出结果:

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

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

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

-3
请尝试这个。
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']

-4
一个非常简单的方法是:
list1=['']
j=0
for i in com_list:
    if j==0:
        list1[0]=(i['value'])
    else:
        list1.append(i['value'])
    j+=1

输出:

['苹果', '香蕉', '汽车']


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接