Создание одной записи JSON из нескольких записей JSON (практика кодирования с высокой производительностью)

#python #json #python-3.x

#python #json #python-3.x

Вопрос:

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

 my_dict = [{'processId': 'p1', 'userId': 'user1', 'reportName': 'report1', 'threadId': '12234', 'some_other_keys': 'respective values.12234'}, {'userId': 'user1', 'processId': 'p1', 'reportName': 'report1', 'threadId': '12335', 'some_other_keys': 'respective values.12335', 'another_key': 'another_value.12335','key1': 'key1_value.12335'}, {'processId': 'p1', 'userId': 'user1', 'reportName': 'report1', 'threadId': '12834', 'some_other_keys': 'respective values.12834','key2': 'key2_value.12834'}]
  

Примечание: разные строки json имеют разный набор ключей.

В этих строках ‘ProcessId’: ‘p1’, ‘userId’: ‘user1’, ‘ReportName’: ‘report1’ одинаковы для всех строк, и это известно программисту.

Цель:

  1. напишите функцию для создания одной строки JSON из приведенных выше.
  2. аргументы функции являются
    1. список совпадающих ключей, т.е. ["processId","userId","reportName"]
    2. словарь, как упоминалось выше.

Вывод:

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

 {"processId": "p1", "userId": "user1", "reportName": "report1", "threadId_0": "12234", "some_other_keys_0": "respective values.12234", "threadId_1": "12335", "some_other_keys_1": "respective values.12335", "another_key_1": "another_value.12335","key1_1": "key1_value.12335", "threadId_2": "12834", "some_other_keys_2": "respective values.12834","key2_2": "key2_value.12834"}
  

Мой текущий код выглядит следующим образом:

 def multijson_to_singlejson_matchingkey(list_json, list_keys):
    rec0 = {}
    for l in range(len(list_keys)):
        key0 = list_keys[l]
        value0 = list_json[0][key0]
        rec0[f'{key0}'] = value0
    rec = {}
    for i in range(len(list_json)):
        line = list_json[i]
        for j in range(len(list_keys)):
            del line[list_keys[j]]
        line_keys = list(line)
        for k in range(len(line_keys)):
            key_a = line_keys[k]   "_"   f"{i}"
            line[f'{key_a}'] = line[f'{line_keys[k]}']
            del line[f'{line_keys[k]}']
        rec = {**rec, **line}
    res = {}
    res = {**rec0, **rec}
    print(res)
    return res
  

Но это функция с 20 строками кода. Я пытаюсь оптимизировать код с меньшим количеством строк кода и повысить его производительность. Нужна помощь с доступными вариантами для этого.

Ответ №1:

Вы можете упростить генерацию rec0 до, надеюсь, разумно читаемой однострочной строки, а затем выполнить цикл по списку входных словарей для заполнения остальных, игнорируя любые ключи, которые есть в list_keys (хотя тестирование здесь эквивалентно rec0 , поскольку это немного быстрее):

 def multi_to_single(list_json, list_keys):
    rec0 = dict((key0, list_json[0][key0]) for key0 in list_keys)
    res = rec0.copy()
    for i, dct in enumerate(list_json):
        for k, v in dct.items():
            if k not in rec0:
                res[f'{k}_{i}'] = v
    print(res)
    return res
  

Это дает ( pprint.pprint здесь вместо print для удобства чтения):

 {'another_key_1': 'another_value.12335',
 'key1_1': 'key1_value.12335',
 'key2_2': 'key2_value.12834',
 'processId': 'p1',
 'reportName': 'report1',
 'some_other_keys_0': 'respective values.12234',
 'some_other_keys_1': 'respective values.12335',
 'some_other_keys_2': 'respective values.12834',
 'threadId_0': '12234',
 'threadId_1': '12335',
 'threadId_2': '12834',
 'userId': 'user1'}