[英]Convert list of dicts into a unique dict
I have: 我有:
[
{'id': 1, 'name': 'foo'},
{'id': 2, 'name': 'bar'},
{'id': 1, 'name': 'gesiel'}
]
I want: 我想要:
{
1: [
{'id': 1, 'name': 'foo'},
{'id': 1, 'name': 'gesiel'}
],
2: [
{'id': 2, 'name': 'bar'}
]
}
This code does this: 这段代码执行此操作:
organized = {d['id']:[] for d in data}
[organized[d['id']].append(d) for d in data]
Is there a more pythonic way to do this? 是否有更多的pythonic方式来做到这一点?
Use collections.defaultdict
: 使用
collections.defaultdict
:
from collections import defaultdict
data = [{'id': 1, 'name': 'foo'}, {'id': 2, 'name': 'bar'}, {'id': 1, 'name': 'gesiel'}]
d = defaultdict(list)
for x in data:
d[x['id']].append(x)
print(d)
# defaultdict(<class 'list'>, {1: [{'id': 1, 'name': 'foo'}, {'id': 1, 'name': 'gesiel'}], 2: [{'id': 2, 'name': 'bar'}]})
Using groupby.itertools we can create this dicitonary 使用groupby.itertools我们可以创建这个dicitonary
from itertools import groupby
lista = [{'id': 1, 'name': 'foo'}, {'id': 2, 'name': 'bar'}, {'id': 1, 'name': 'gesiel'}]
d = {}
for k, g in groupby(sorted(lista, key=lambda x: x['id']), key=lambda x: x['id']):
d[k] = list(g)
# {1: [{'id': 1, 'name': 'foo'}, {'id': 1, 'name': 'gesiel'}], 2: [{'id': 2, 'name': 'bar'}]}
or using dictionary comprehension 或使用字典理解
d = {k: list(g) for k, g in groupby(sorted(lista, key=lambda x: x['id']), key=lambda x: x['id'])}
There is nothing wrong with a 2-pass O( n ) solution if you are, as here, working with an in-memory object. 如果你在这里使用内存中的对象,那么2遍O( n )解决方案没有任何问题。 The main issue with your code is you are misusing the list comprehension.
您的代码的主要问题是您滥用列表理解。
A list comprehension should be used to construct a new list, not to process an in-place function or method in a loop. 应使用列表推导来构造新列表,而不是在循环中处理就地函数或方法。 Taking your example, your logic will create a list which looks like:
举个例子,你的逻辑将创建一个如下所示的列表:
[None, None, None, ..., None]
The side-effect of the comprehension means that organized
values have items appended to them as required. 理解的副作用意味着
organized
值根据需要附加了项目。 Instead, you can rewrite using a simple for
loop: 相反,您可以使用简单的
for
循环重写:
organized = {d['id']: [] for d in data}
for d in data:
organized[d['id']].append(d)
Your logic can be made more efficient by not adding keys via an initial iteration. 通过不通过初始迭代添加键,可以提高逻辑效率。 This common problem is resolved by
collections.defaultdict
, as in @Austin's solution . 这个常见问题由
collections.defaultdict
解决,就像在@Austin的解决方案中一样 。 This solution gives an empty list for any key which does not exist: 此解决方案为任何不存在的键提供一个空列表:
from collections import defaultdict
res = defaultdict(list)
for d in data:
res[d['i']].append(d)
print(res)
defaultdict(list,
{1: [{'id': 1, 'name': 'foo'}, {'id': 1, 'name': 'gesiel'}],
2: [{'id': 2, 'name': 'bar'}]})
Since defaultdict
is a subclass of dict
, there's usually no need to convert this back to a regular dictionary. 由于
defaultdict
是dict
的子类,因此通常无需将其转换回常规字典。
Austin's answer is better, but here method just using dict
s 奥斯汀的答案更好,但这里的方法只是使用
dict
s
In [175]: data = [{'id': 1, 'name': 'foo'}, {'id': 2, 'name': 'bar'}, {'id': 1, 'name': 'gesiel'}]
In [176]: organised = {}
In [177]: for d in data:
...: if d['id'] in organised:
...: organised[d['id']].append(d)
...: else:
...: organised[d['id']] = [d]
...:
In [178]: organised
Out[178]:
{1: [{'id': 1, 'name': 'foo'}, {'id': 1, 'name': 'gesiel'}],
2: [{'id': 2, 'name': 'bar'}]}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.