从字典列表中获取值列表

Posted

技术标签:

【中文标题】从字典列表中获取值列表【英文标题】:Getting a list of values from a list of dicts 【发布时间】:2011-11-08 10:42:46 【问题描述】:

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

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

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

最好的方法是什么?

【问题讨论】:

【参考方案1】:

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

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

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

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

【讨论】:

要处理键的缺失值,也可以使用 d.get("key_to_lookup", "alternate_value")。然后,它看起来像: [d.get('value', 'alt') for d in l] 。如果 value 不作为 key 存在,它将简单地返回 'alt'。 这种“魔法”被称为列表理解docs.python.org/3/tutorial/… 救命稻草!长期以来,我一直在尝试/搜索 sqlalchemy 对象。现在它像[d.value for d in l]一样工作,谢谢:)【参考方案2】:
[x['value'] for x in list_of_dicts]

【讨论】:

或 [d.getkey('value') for d in dict_list] @rpInt 嗯,没有getkey..你的意思是d.get('value')吗?这与@isbadawi 的第二个列表理解相同,而不是 Michal 的。 是的,对不起,我的意思是得到。我的意思是,如果缺少密钥,它不会引发异常。但是@isbadawi 的解决方案更好,因为当密钥丢失时 get() 将提供 None (或我们指定的默认值)。【参考方案3】:

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

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

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

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

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

更新:我也不是 lambdas 的忠实粉丝,我更喜欢命名...这就是我将这样做的方式:

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

【讨论】:

列表理解在这里更有意义。 如果您要使用第一个map,请使用operator.itemgetter('value'),而不是lambda【参考方案4】:

对于这样一个非常简单的情况,理解,如Ismail Badawi's answer 绝对是要走的路。

但是当事情变得更加复杂,并且您需要开始编写包含复杂表达式的多子句或嵌套推导式时,就值得研究其他替代方案。有几种不同的(准)标准方法可以在嵌套的 dict-and-list 结构(例如 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' 的路径而不是一个理解子句会产生很大的不同。此外,JSONPath 是一种与语言无关的规范,甚至还有 online testers 可以非常方便地进行调试。

【讨论】:

【参考方案5】:

一个非常简单的方法是:

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

输出:

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

【讨论】:

【参考方案6】:

我认为像下面这样简单可以满足您的需求。

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)

如您所见,生成器与其他解决方案相比是更好的解决方案,地图也比生成器慢,原因我将留给 OP 来解决。

【讨论】:

【参考方案7】:

按照示例进行操作 --

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

【讨论】:

【参考方案8】:

从python中的字典列表中获取键值?

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

【讨论】:

【参考方案9】:

请试试这个。

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

【讨论】:

以上是关于从字典列表中获取值列表的主要内容,如果未能解决你的问题,请参考以下文章

如何从字典列表中获取值 - Python 3.7.1 [重复]

如何从python中的字典列表中获取值?

如何从字典中获取列表[重复]

从列表字典创建新的字符串列表(即从具有字符串列表作为值的字典)

Django模板:从字典访问值列表

在包含字典的列表中获取最小值(键,值)