[英]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方式來做到這一點?
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'}]})
由於defaultdict
是dict
的子類,因此通常無需將其轉換回常規字典。
奧斯汀的答案更好,但這里的方法只是使用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.