Sup*_*ing 148 python dictionary list
我有一个像这样的字典列表:
[{'value': 'apple', 'blah': 2},
{'value': 'banana', 'blah': 3} ,
{'value': 'cars', 'blah': 4}]
Run Code Online (Sandbox Code Playgroud)
我想要 ['apple', 'banana', 'cars']
什么是最好的方法呢?
Ism*_*awi 270
假设每个dict都有一个value
键,你可以写(假设你的列表被命名l
)
[d['value'] for d in l]
Run Code Online (Sandbox Code Playgroud)
如果value
可能丢失,您可以使用
[d['value'] for d in l if 'value' in d]
Run Code Online (Sandbox Code Playgroud)
Anl*_*ler 30
这是使用map()和lambda函数执行此操作的另一种方法:
>>> map(lambda d: d['value'], l)
Run Code Online (Sandbox Code Playgroud)
其中l是列表.我认为这种方式"最性感",但我会使用列表理解来做到这一点.
更新:如果关键用途可能缺少"值":
>>> map(lambda d: d.get('value', 'default value'), l)
Run Code Online (Sandbox Code Playgroud)
更新:我也不是lambdas的忠实粉丝,我更喜欢命名...这就是我想要的方式:
>>> import operator
>>> map(operator.itemgetter('value'), l)
Run Code Online (Sandbox Code Playgroud)
我甚至会更进一步,创建一个唯一的功能,明确说明我想要实现的目标:
>>> import operator, functools
>>> get_values = functools.partial(map, operator.itemgetter('value'))
>>> get_values(l)
... [<list of values>]
Run Code Online (Sandbox Code Playgroud)
使用Python 3,因为map
返回一个迭代器,用于list
返回一个列表,例如list(map(operator.itemgetter('value'), l))
.
Mic*_*bus 17
[x['value'] for x in list_of_dicts]
Run Code Online (Sandbox Code Playgroud)
使用列表理解
输入:
d = [{'value': 'apple', 'blah': 2}, {'value': 'banana', 'blah': 3}, {'value': 'cars', 'blah': 4}]
values = [i['value'] for i in d]
print(values)
Run Code Online (Sandbox Code Playgroud)
输出:
['apple', 'banana', 'cars']
Run Code Online (Sandbox Code Playgroud)
我认为如下简单的内容就能满足您的需求。
\n\nIn[5]: ll = [{'value': 'apple', 'blah': 2}, {'value': 'banana', 'blah': 3} , {'value': 'cars', 'blah':4}]\nIn[6]: ld = [d.get('value', None) for d in ll]\nIn[7]: ld\nOut[7]: ['apple', 'banana', 'cars']\n
Run Code Online (Sandbox Code Playgroud)\n\n您可以结合使用map
和来完成此操作lambda
您也
对于较小的输入列表理解是一种方法,但如果输入真的很大,那么我想生成器是理想的方法。
\n\nIn[11]: gd = (d.get('value', None) for d in ll)\nIn[12]: gd\nOut[12]: <generator object <genexpr> at 0x7f5774568b10>\nIn[13]: '-'.join(gd)\nOut[13]: 'apple-banana-cars'\n
Run Code Online (Sandbox Code Playgroud)\n\n这是针对更大输入的所有可能解决方案的比较
\n\n In[2]: l = [{'value': 'apple', 'blah': 2}, {'value': 'banana', 'blah': 3} , {'value': 'cars', 'blah':4}] * 9000000\nIn[3]: def gen_version():\n ...: for i in l:\n ...: yield i.get('value', None)\n ...: \nIn[4]: def list_comp_verison():\n ...: return [i.get('value', None) for i in l]\n ...: \nIn[5]: def list_verison():\n ...: ll = []\n ...: for i in l:\n ...: ll.append(i.get('value', None))\n ...: return ll\nIn[10]: def map_lambda_version():\n ...: m = map(lambda i:i.get('value', None), l)\n ...: return m\n ...: \nIn[11]: %timeit gen_version()\n172 ns \xc2\xb1 0.393 ns per loop (mean \xc2\xb1 std. dev. of 7 runs, 10000000 loops each)\nIn[12]: %timeit map_lambda_version()\n203 ns \xc2\xb1 2.31 ns per loop (mean \xc2\xb1 std. dev. of 7 runs, 1000000 loops each)\nIn[13]: %timeit list_comp_verison()\n1.61 s \xc2\xb1 20.4 ms per loop (mean \xc2\xb1 std. dev. of 7 runs, 1 loop each)\nIn[14]: %timeit list_verison()\n2.29 s \xc2\xb1 4.58 ms per loop (mean \xc2\xb1 std. dev. of 7 runs, 1 loop each)\n
Run Code Online (Sandbox Code Playgroud)\n\n正如你所看到的,与其他解决方案相比,生成器是一个更好的解决方案,与生成器相比,地图也更慢,原因我将留给 OP 来弄清楚。
\n对于这样一个非常简单的案例,理解,就像Ismail Badawi 的答案一样,绝对是要走的路。
但是,当事情变得更加复杂,并且您需要开始编写包含复杂表达式的多子句或嵌套推导式时,就值得研究其他替代方案。有几种不同的(准)标准方法可以在嵌套的 dict-and-list 结构上指定 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'}]}
Run Code Online (Sandbox Code Playgroud)
或者,使用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']
Run Code Online (Sandbox Code Playgroud)
这个乍一看可能不那么简单,因为find
返回匹配对象,除了匹配的值之外还包括所有类型的东西,例如直接到每个项目的路径。但是对于更复杂的表达式,能够'*.[*].value'
为每个表达式指定一个路径而不是理解子句*
会产生很大的不同。此外,JSONPath 是一种与语言无关的规范,甚至还有在线测试人员可以非常方便地进行调试。
归档时间: |
|
查看次数: |
155283 次 |
最近记录: |