Python: проанализируйте Json, чтобы найти совпадающие строки, соответствующие нескольким ключам, и верните каждый соответствующий набор как единый в виде отдельной записи json

#python #json #python-3.x

#python #json #python-3.x

Вопрос:

У меня есть JSON, который выглядит как показано ниже.

 {"processId":"p1","userId":"user1","reportName":"report1","threadId": "12234", "some_other_keys":"respective values"}
{"userId":"user1","processId":"p1","reportName":"report1","threadId":"12335", "some_other_keys":"respective values"}
{"reportName":"report2","processId":"p1","userId":"user1","threadId":"12434", "some_other_keys":"respective values"}
{"threadId":"12734", "some_other_keys":"respective values", "processId":"p1","userId":"user2","reportName":"report1"}
{"processId":"p1","reportName":"report1","threadId":"12534", "some_other_keys":"respective values","userId":"user2"}
{"processId":"p1","userId":"user1","reportName":"report2","threadId":"12934", "some_other_keys":"respective values"}
{"processId":"p1","userId":"user1","reportName":"report1","threadId":"12834", "some_other_keys":"respective values"}
{"processId":"p1","userId":"user1","reportName":"report2","threadId":"12634", "some_other_keys":"respective values"}
  

Цель: написать функцию, которая возвращает все разные наборы строк, которые имеют одинаковые значения «ProcessId», «userId», «ReportName» в виде одной записи JSON с измененными именами ключей для каждой совпадающей записи, как показано ниже.

В приведенном выше примере имеется три совпадающих набора.

Set1 (для «ProcessId»: «p1», «userId»: «user1», «ReportName»: «report1»):

 {"processId":"p1","userId":"user1","reportName":"report1","threadId":"12234", "some_other_keys":"respective values"}
{"userId":"user1","processId":"p1","reportName":"report1","threadId":"12335", "some_other_keys":"respective values"}
{"processId":"p1","userId":"user1","reportName":"report1","threadId":"12834", "some_other_keys":"respective values"}
  

Set2 («ProcessId»: «p1», «userId»: «user1», «ReportName»: «report2»):

 {"reportName":"report2","processId":"p1","userId":"user1","threadId":"12434", "some_other_keys":"respective values"}
{"processId":"p1","userId":"user1","reportName":"report2","threadId":"12934", "some_other_keys":"respective values"}
{"processId":"p1","userId":"user1","reportName":"report2","threadId":"12634", "some_other_keys":"respective values"}
  

Set3 («ProcessId»: «p1», «userId»: «user2», «ReportName»: «report2»):

 {"threadId":"12734", "some_other_keys":"respective values", "processId":"p1","userId":"user2","reportName":"report1"}
{"processId":"p1","reportName":"report1","threadId":"12534", "some_other_keys":"respective values","userId":"user2"}
  

Итак, в этом конкретном примере функция должна возвращать три разных набора, как показано ниже.

Set1 (для «ProcessId»: «p1», «userId»: «user1», «ReportName»: «report1»): {"processId":"p1","userId":"user1","reportName":"report1","threadId_1":"12234", "some_other_keys_1":"respective values", "threadId_2":"12335", "some_other_keys_2":"respective values", "threadId_3":"12834", "some_other_keys_3":"respective values"}

Set2 («ProcessId»: «p1», «userId»: «user1», «ReportName»: «report2»): {"processId":"p1","userId":"user1","reportName":"report2","threadId_1":"12934", "some_other_keys_1":"respective values","threadId_2":"12434", "some_other_keys_2":"respective values","threadId_3":"12634", "some_other_keys_3":"respective values"}

Set3 («ProcessId»: «p1», «userId»: «user2», «ReportName»: «report2»): {"threadId_1":"12734", "some_other_keys_1":"respective values", "processId":"p1","userId":"user2","reportName":"report1""threadId_2":"12534", "some_other_keys_2":"respective values"}

Итак, одна функция возвращает три набора (это может быть больше или меньше, также в зависимости от количества совпадающих наборов)

Мне нужно решение вышеупомянутой проблемы в виде (а) кода с высокой производительностью (б) кода с меньшим количеством строк, поскольку я буду обрабатывать большое количество строк. Итак, я хочу, чтобы мой код выполнялся быстрее, а также чтобы в коде было меньше строк.

Комментарии:

1. Вы пробовали это самостоятельно?

2. Предоставленный входной JSON не является JSON, пожалуйста, исправьте это. Кроме того, вы сами что-нибудь пробовали?

3. Откуда берутся входные данные? Это недопустимый формат JSON, поэтому я предполагаю, что это созданный вами пользовательский формат?

Ответ №1:

 import json

f = open('data.json')
data = json.load(f)
f.close()

sets_of_procces = dict()

for item in data:
    set_id = processId, userId, reportName = item['processId'], item['userId'], item['reportName']
    if set_id not in sets_of_procces.keys():
        sets_of_procces[set_id] = []
    thread_number = len(sets_of_procces[set_id])   1
    thread_data = { f'threadId_{thread_number}' : item['threadId'], f'some_other_keys_{thread_number}' : item['some_other_keys'] }
    sets_of_procces[set_id].append(json.dumps(thread_data))

for i, procces_set in enumerate(sets_of_procces):
    print(f'Set {i 1} : n')
    processId, userId, reportName = procces_set
    json_dict = { 'processId' : processId, 'userId' : userId, 'reportName' : reportName }
    for item in sets_of_procces[procces_set]:
        json_dict = {**json_dict, **json.loads(item)}
    print(json.dumps(json_dict))

  

Комментарии:

1. Привет, спасибо за ваш ответ, но это не соответствует моим ожиданиям . Ожидаемый результат (для одного из наборов): {"processId":"p1","userId":"user1","reportName":"report1","threadId_1":"12234", "some_other_keys_1":"respective values", "threadId_2":"12335", "some_other_keys_2":"respective values", "threadId_3":"12834", "some_other_keys_3":"respective values"} т.е. одна запись json внутри {} для каждого соответствующего набора с измененными именами для нескольких ключей (как _1, _2 и т.д.).

2. Вот так @SaurabhChakrabarty