将dict列表转换为唯一的di

2024-06-07 13:46:46 发布

您现在位置:Python中文网/ 问答频道 /正文

我有:

[
  {'id': 1, 'name': 'foo'},
  {'id': 2, 'name': 'bar'},
  {'id': 1, 'name': 'gesiel'}
]

我想要:

{
  1: [
    {'id': 1, 'name': 'foo'},
    {'id': 1, 'name': 'gesiel'}
  ],
  2: [
    {'id': 2, 'name': 'bar'}
  ]
}

此代码执行以下操作:

organized = {d['id']:[] for d in data}
[organized[d['id']].append(d) for d in data]

有没有更像Python的方法?你知道吗


Tags: 方法nameinidfordatafoobar
3条回答

使用^{}

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

使用groupby.iter工具我们可以创建这个

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

或使用词典理解

d = {k: list(g) for k, g in groupby(sorted(lista, key=lambda x: x['id']), key=lambda x: x['id'])}

如果您像这里一样处理内存中的对象,那么2-passo(n)解决方案没有什么问题。代码的主要问题是您误用了列表理解。你知道吗

列表理解应该用来构造一个新的列表,而不是在循环中处理一个就地函数或方法。以您的示例为例,您的逻辑将创建一个如下所示的列表:

[None, None, None, ..., None]

理解的副作用意味着organized值会根据需要添加项。相反,您可以使用一个简单的for循环重写:

organized = {d['id']: [] for d in data}

for d in data:
    organized[d['id']].append(d)

通过而不是通过初始迭代添加键,可以提高逻辑的效率。这个常见问题由^{}解决,如@Austin's solution。此解决方案为不存在的任何键提供空列表:

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

因为defaultdictdict的子类,所以通常不需要将其转换回常规字典。你知道吗

相关问题 更多 >

    热门问题