[英]Merge dictionaries with same key from two lists of dicts in python
我有兩本字典,如下所示。 兩個詞典都有一個詞典列表作為與其properties
鍵關聯的值; 這些列表中的每個字典都有一個id
鍵。 我希望將我的兩個詞典合並為一個,這樣生成的詞典中的properties
列表每個id
只有一個詞典。
{
"name":"harry",
"properties":[
{
"id":"N3",
"status":"OPEN",
"type":"energetic"
},
{
"id":"N5",
"status":"OPEN",
"type":"hot"
}
]
}
和另一個列表:
{
"name":"harry",
"properties":[
{
"id":"N3",
"type":"energetic",
"language": "english"
},
{
"id":"N6",
"status":"OPEN",
"type":"cool"
}
]
}
我要實現的 output 是:
"name":"harry",
"properties":[
{
"id":"N3",
"status":"OPEN",
"type":"energetic",
"language": "english"
},
{
"id":"N5",
"status":"OPEN",
"type":"hot"
},
{
"id":"N6",
"status":"OPEN",
"type":"cool"
}
]
}
由於id: N3
在兩個列表中都很常見,因此這兩個字典應該與所有字段合並。 到目前為止,我已經嘗試使用itertools
和
ds = [d1, d2]
d = {}
for k in d1.keys():
d[k] = tuple(d[k] for d in ds)
有人可以幫忙解決這個問題嗎?
將這兩個對象視為各自列表中的元素可能會有所幫助。 也許您有其他具有不同name
值的對象,例如可能來自 JSON 格式的 REST 請求。
然后你可以對name
和id
鍵進行左外連接:
#!/usr/bin/env python
a = [
{
"name": "harry",
"properties": [
{
"id":"N3",
"status":"OPEN",
"type":"energetic"
},
{
"id":"N5",
"status":"OPEN",
"type":"hot"
}
]
}
]
b = [
{
"name": "harry",
"properties": [
{
"id":"N3",
"type":"energetic",
"language": "english"
},
{
"id":"N6",
"status":"OPEN",
"type":"cool"
}
]
}
]
a_names = set()
a_prop_ids_by_name = {}
a_by_name = {}
for ao in a:
an = ao['name']
a_names.add(an)
if an not in a_prop_ids_by_name:
a_prop_ids_by_name[an] = set()
for ap in ao['properties']:
api = ap['id']
a_prop_ids_by_name[an].add(api)
a_by_name[an] = ao
res = []
for bo in b:
bn = bo['name']
if bn not in a_names:
res.append(bo)
else:
ao = a_by_name[bn]
bp = bo['properties']
for bpo in bp:
if bpo['id'] not in a_prop_ids_by_name[bn]:
ao['properties'].append(bpo)
res.append(ao)
print(res)
上面的想法是處理列表a
的名稱和 ID。 names 和 ids-by-name 是 Python set
的實例。 所以成員總是唯一的。
一旦你有了這些集合,你就可以對列表b
的內容進行左外連接。
b 中存在 object 而b
中不a
(即共享一個通用name
),在這種情況下,您可以將 object 按原樣添加到結果中。 但是,如果b
中有一個 object 確實存在於a
(共享一個公共name
)中,那么您將迭代該對象的id
值並查找尚未在a
ids-by-name 集中的 ids。 您將缺少的屬性添加到a
中,然后將處理后的 object 添加到結果中。
Output:
[{'name': 'harry', 'properties': [{'id': 'N3', 'status': 'OPEN', 'type': 'energetic'}, {'id': 'N5', 'status': 'OPEN', 'type': 'hot'}, {'id': 'N6', 'status': 'OPEN', 'type': 'cool'}]}]
這不會對輸入進行任何錯誤檢查。 這依賴於每個 object 中唯一的name
值。因此,如果您在兩個列表中的對象中有重復的鍵,您可能會得到垃圾(不正確或意外的輸出)。
這是其中一種方法:
a = {
"name":"harry",
"properties":[
{
"id":"N3",
"status":"OPEN",
"type":"energetic"
},
{
"id":"N5",
"status":"OPEN",
"type":"hot"
}
]
}
b = {
"name":"harry",
"properties":[
{
"id":"N3",
"type":"energetic",
"language": "english"
},
{
"id":"N6",
"status":"OPEN",
"type":"cool"
}
]
}
# Create dic maintaining the index of each id in resp dict
a_ids = {item['id']: index for index,item in enumerate(a['properties'])} #{'N3': 0, 'N5': 1}
b_ids = {item['id']: index for index,item in enumerate(b['properties'])} #{'N3': 0, 'N6': 1}
# Loop through one of the dict created
for id in a_ids.keys():
# If same ID exists in another dict, update it with the key value
if id in b_ids:
b['properties'][b_ids[id]].update(a['properties'][a_ids[id]])
# If it does not exist, then just append the new dict
else:
b['properties'].append(a['properties'][a_ids[id]])
print (b)
Output:
{'name': 'harry', 'properties': [{'id': 'N3', 'type': 'energetic', 'language': 'english', 'status': 'OPEN'}, {'id': 'N6', 'status': 'OPEN', 'type': 'cool'}, {'id': 'N5', 'status': 'OPEN', 'type': 'hot'}]}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.