Python 合并 2 个 DICT 对象,如果与列表中的 id 匹配,则使用分隔符

Python Merge 2 DICT objects if matching id within a list with separators

提问人:Nico44044 提问时间:10/3/2023 更新时间:10/3/2023 访问量:49

问:

在 Python 中,我有这 2 个 dicts 对象:

dict1 = [{'id_contact': '1', 'name': 'Rick'},{'id_contact': '9', 'name': 'John'}]

dict2 = [{'id_company': ';1;3;4;11;', 'company_name': 'Nike'},{'id_company': ';1;2;9;', 'company_name': 'Adidas'}]

我想将这 2 个字典合并到一个新的字典中,以添加 dict1 的 if 在 dict2 中找到。 如果有几个匹配项,我想使用“;”作为分隔符'company_name'id_contactid_company'company_name'

预期结果是:

dictmerge = [{'id_contact': '1', 'name': 'Rick', 'company_name': 'Nike;Adidas'},{'id_contact': '9', 'name': 'John', 'company_name': 'Adidas'}]

感谢您的帮助。

python 字典 合并 匹配 部分

评论

0赞 Tzane 10/3/2023
问题到底是什么?
0赞 DeepSpace 10/3/2023
您对这些输入的创建有任何控制权吗?由于两者都是列表,因此您可以拥有的最有效的解决方案将是 O(n^2)。为什么不让其中至少一个成为口述呢?假设是唯一的,实际上可以是一个字典而不是一个列表id_contactdict1
0赞 Nico44044 10/3/2023
不幸的是,不,我无法更改字典的生成方式。这就是我在这里寻求帮助的原因

答:

1赞 mozway 10/3/2023 #1

初始说明:dict1dict1 是(字典)列表,而不是字典。

您需要执行几个步骤,首先循环以聚合每个 ID 的公司名称,然后将其扁平化为字符串。最后,循环并添加缺少的密钥:dict2dict1

companies = {}
for d in dict2:
    for i in d.get('id_company', '').strip(';').split(';'):
        companies.setdefault(i, []).append(d['company_name'])
companies = {i: ';'.join(v) for i, v in companies.items()}
# {'1': 'Nike;Adidas', '3': 'Nike', '4': 'Nike', '11': 'Nike',
#  '2': 'Adidas', '9': 'Adidas'}

for d in dict1:
    d['company_name'] = companies.get(d['id_contact'])

print(dict1)

输出:

[{'id_contact': '1', 'name': 'Rick', 'company_name': 'Nike;Adidas'},
 {'id_contact': '9', 'name': 'John', 'company_name': 'Adidas'}]

评论

0赞 Nico44044 10/3/2023
谢谢。我真的很喜欢这个解决方案。在我接受之前的最后一个问题,如果没有匹配,你会如何调整这个答案?例如,如果 dict1 : {'id_contact': '5', 'name': 'Donna'} 中存在这个,则 ID 5 将与任何 dict2 ID 不匹配。所以我希望在这种情况下的结果: {'id_contact': '5', 'name': 'Donna', 'company_name': ''} 但到目前为止,它会产生一个错误“can' find variable: None”
0赞 Nico44044 10/3/2023
没关系,我通过在您的回答中修改它来成功: for d in dict1: if companies.get(d['id_contact']) == None: d['company_name'] = ' ' else: d['company_name'] = companies.get(d['id_contact'])
1赞 mozway 10/4/2023
您可以直接使用:d['company_name'] = companies.get(d['id_contact'], '') ;)
0赞 Nico44044 10/5/2023
谢谢,我会修改答案。谢谢你最初的笔记,我也学到了一些东西,并尽量不要在将来犯错误。
1赞 Patryk Opiela 10/3/2023 #2

我建议将id_company保留在列表中,而不是创建新光盘,而是在 dict1 中为公司名称添加新字段。

现在代码将如下所示,

peopleDict = [
{
    'id_contact': 1, 
    'name': 'Rick',
    'company_name': [],
 },
{
    'id_contact': 9, 
    'name': 'John',
    'company_name': [],
}
]

companyDict = [
    {
        'id_company': [1,3,4,11], 
        'company_name': 'Nike'
        },
    {
        'id_company': [1,2,9], 
        'company_name': 'Adidas'
    }
]

for person in peopleDict:
    for company in companyDict:
        if person.get('id_contact') in company.get('id_company'):
            person['company_name'].append(company.get('company_name'))

print(peopleDict)