簡體   English   中英

將dicts列表轉換為唯一的dict

[英]Convert list of dicts into a unique dict

我有:

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

是否有更多的pythonic方式來做到這一點?

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

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

或使用字典理解

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

如果你在這里使用內存中的對象,那么2遍O( n )解決方案沒有任何問題。 您的代碼的主要問題是您濫用列表理解。

應使用列表推導來構造新列表,而不是在循環中處理就地函數或方法。 舉個例子,你的邏輯將創建一個如下所示的列表:

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

理解的副作用意味着organized值根據需要附加了項目。 相反,您可以使用簡單的for循環重寫:

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

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

通過通過初始迭代添加鍵,可以提高邏輯效率。 這個常見問題由collections.defaultdict解決,就像在@Austin的解決方案中一樣 此解決方案為任何不存在的鍵提供一個空列表:

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的子類,因此通常無需將其轉換回常規字典。

奧斯汀的答案更好,但這里的方法只是使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM