добавить все значения в dict, если все элементы существуют, и удалить дубликаты - PullRequest
0 голосов
/ 16 апреля 2020

У меня есть сценарий, в котором у меня есть три словаря, которые я хочу объединить в один, но при этом я сравниваю три словаря с ключом name, если есть дубликаты, необходимо удалить их.

Вот то, что я пробовал:

dict1= {'d1': [{'name': 'app1', 'id': 7134}, {'name': 'app2', 'id': 242}, {'name': 'yest app', 'id': 67},{'name': 'abc jam app', 'id': 6098}]}

dict2= {'d2': [{'name': 'app1 ', 'id': 30}, {'name': 'app2', 'id': 82}, {'name': 'yest app', 'id': 17}]}

dict3= {'d3': [{'name': 'app1', 'id': 70}, {'name': 'app2', 'id': 2582},{'name': 'availabla2z', 'id': 6667}]}

dict2 = {i:j for i,j in dict2.items() if i not in dict1}
dict3 = {i:j for i,j in dict3.items() if i not in dict2}

Но то же самое не дает результатов, и я не уверен, как сравнить три диктанта по этому вопросу. и так как, если вы посмотрите на данные, dict1 имеет элемент 'name': 'app1', где такой же элемент присутствует в dict2, как этот 'name': 'app1 ' (с пробелом), не уверен, как это отформатировать и получить окончательный вариант, как показано ниже.

{'final': [{'name': 'app1 ', 'id': 30}, {'name': 'app2', 'id': 82}, {'name': 'yest app', 'id': 17},{'name': 'abc jam app', 'id': 6098},{'name': 'availabla2z', 'id': 6667}]}

Ответы [ 3 ]

1 голос
/ 16 апреля 2020

Вот решение, использующее преимущества этого другого ответа SO (полезно для python -2.x альтернатив), которое удалит дубликаты без какого-либо конкретного правила:

final_dict = dict()
final_dict["final"] = dict1["d1"] + dict2["d2"] + dict3["d3"]
final_dict["final"] = list(
    {v['name'].strip():v for v in final_dict["final"]}.values()
)  # see usage of .strip() to handle space problems you mention

print(final_dict)

Результат:

{'final': [
  {'name': 'app1', 'id': 70},
  {'name': 'app2', 'id': 2582},
  {'name': 'yest app', 'id': 17},
  {'name': 'abc jam app', 'id': 6098},
  {'name': 'availabla2z', 'id': 6667}]
}
0 голосов
/ 16 апреля 2020

Вы можете сгруппировать все словари вместе по name, используя defaultdict:

from collections import defaultdict

d = defaultdict(list)
for lst in (dict1.values(), dict2.values(), dict3.values()):
    for sublst in lst:
        for dic in sublst:
            d[dic["name"].strip()].append(dic)

Затем выберите словари с наименьшим значением id, используя min(). Это все еще работает для требований, так как оно все еще выбирает один словарь и соответствует запрошенному выводу.

from operator import itemgetter

result = {'field': [min(x, key=itemgetter('id')) for x in d.values()]}

print(result)

Выход:

{'field': [{'name': 'app1', 'id': 30}, {'name': 'app2', 'id': 82}, {'name': 'yest app', 'id': 17}, {'name': 'abc jam app', 'id': 6098}, {'name': 'availabla2z', 'id': 6667}]}
0 голосов
/ 16 апреля 2020

Вот рабочий код обновления:

dict1= {'d1': [{'name': 'app1', 'id': 7134}, {'name': 'app2', 'id': 242}, {'name': 'yest app', 'id': 67},{'name': 'abc jam app', 'id': 6098}]}
dict2= {'d2': [{'name': 'app1 ', 'id': 30}, {'name': 'app2', 'id': 82}, {'name': 'yest app', 'id': 17}]}
dict3= {'d3': [{'name': 'app1', 'id': 70}, {'name': 'app2', 'id': 2582},{'name': 'availabla2z', 'id': 6667}]}
final = {'final':[]}
for i in dict1['d1']:
    final['final'].append(i)

for k,l in zip(dict3['d3'],range(len(dict1['d1']))):
    if k['name'] == final['final'][l]['name']:
        final['final'][l].update(k)
    else:
        final['final'].append(k)
for j,l in zip(dict2['d2'],range(len(dict1['d1']))):
    if j['name'].strip() == final['final'][l]['name'].strip():
        final['final'][l].update(j)
    else:
        final['final'].append(j)

Это дает:

{'final': [{'name': 'app1 ', 'id': 30}, {'name': 'app2', 'id': 82}, {'name': 'yest app', 'id': 17}, {'name': 'abc jam app', 'id': 6098}, {'name': 'availabla2z', 'id': 6667}]}
...