提问人:Sharmat 提问时间:7/24/2023 最后编辑:Sharmat 更新时间:7/24/2023 访问量:65
蟒。按相似项目比较和合并词典列表(多样化)
Python. Compare and merge lists of dictionaries(diversed) by similar items
问:
我有两个词典列表(lod)。如果它们具有相似的项目(通过键和 ),我想比较和合并它们,如果没有将某些默认值(0)与某些 key() 设置为第一个 lod。'id'
'size'
'count'
lod1 = [{'id':1, 'size':1, 'colour':'a'}, {'id':1, 'size':2, 'colour':'ab'}, {'id':2, 'size':1, 'colour':'ab'}, {'id':2, 'size':2, 'colour':'ab'}]
lod2 = [{'id':1, 'size':1, 'count':1}, {'id':1, 'size':2, 'count':2}, {'id':2, 'size':1, 'count':3}]
输出:
merged = [{'id':1, 'size':1, 'colour':'a', 'count': 1}, {'id':1, 'size':2, 'colour':'ab', 'count': 2}, {'id':2, 'size':1, 'colour':'ab', 'count':3}, {'id':2, 'size':2, 'colour':'ab', 'count': 0}]
我提请你注意{'id':2 , 'size':2, 'colour':'ab', 'count': 0}
关于比较和合并 lod 有很多类似的问题和解决方案,但并不相同。我知道这样做的方法,但它看起来太笨重、笨拙和不优雅了。
我的解决方案:
def merge(l1, l2):
lod1_pairs = [(i['id'], i['size']) for i in l1]
lod2_pairs = [(i['id'], i['size']) for i in l2]
mismatched = [pair for pair in lod1_pairs if pair not in lod2_pairs]
# we get list of unique pairs of lod1 to set default value to 'count' key.
merged = []
for i in lod1:
if (i['id'], i['size']) in mismatched:
#immediately cut off and evaluate 'count' key for the mismatched keys
temp_dict = i| {'count': 0}
merged.append(temp_dict)
else:
for j in lod2:
#straightly compare key values
if i['id'] == j['id'] and i['size'] == j['size']:
temp_dict = i | j #merge dicts
merged.append(temp_dict)
return merged
lod1 = [{'id':1, 'size':1, 'colour':'a'}, {'id':1 , 'size':2, 'colour':'ab'}, {'id':2, 'size':1, 'colour':'ab'}, {'id':2, 'size':2, 'colour':'ab'}]
lod2 = [{'id':1, 'size':1, 'count':1}, {'id':1, 'size':2, 'count':2}, {'id':2, 'size':1, 'count':3}]
merged = merge(lod1,lod2)
我有过使用 defaultdict 的经验,并查看了一个 DeepDiff 库,但不明白如何在这里使用它们。
答:
1赞
Andrej Kesely
7/24/2023
#1
您可以尝试:
out = {(d["id"], d["size"]): {**d, "count": 0} for d in lod1}
for d in lod2:
t = d["id"], d["size"]
if t in out:
out[t]["count"] = d["count"]
else:
out[t] = d
print(list(out.values()))
指纹:
[
{"id": 1, "size": 1, "colour": "a", "count": 1},
{"id": 1, "size": 2, "colour": "ab", "count": 2},
{"id": 2, "size": 1, "colour": "ab", "count": 3},
{"id": 2, "size": 2, "colour": "ab", "count": 0},
]
1赞
Maria K
7/24/2023
#2
版本略有不同,不使用 if..还:
def merge(lod1, lod2):
dod2 = {(dct['id'], dct['size']): dct['count'] for dct in lod2}
merged = []
for entry in lod1:
merged.append(entry)
merged[-1]['count'] = dod2.get((entry['id'], entry['size']), 0)
return merged
merge(lod1, lod2)
输出:
[{'id': 1, 'size': 1, 'colour': 'a', 'count': 1},
{'id': 1, 'size': 2, 'colour': 'ab', 'count': 2},
{'id': 2, 'size': 1, 'colour': 'ab', 'count': 3},
{'id': 2, 'size': 2, 'colour': 'ab', 'count': 0}]
评论
0赞
Sharmat
7/28/2023
Спасибо, Мария!
0赞
Maria K
7/28/2023
Рада помочь!:)
评论
{'id':2, 'size':1, 'colour':'ab'}
count
{'id':1, 'size':1, 'colour':'a'}
{'id':1, 'size':1, 'count':1}
{'id':1, 'size':1, 'colour':'a', count':1}
'id'
'size'
lod1
{'count':0}
{'id':2, 'size':2, 'colour':'ab'}
-->{'id':2, 'size':2, 'colour':'ab', 'count':0}