Строка дубликатов в словаре файла json не может быть проанализирована на пару ключ / значение - PullRequest
1 голос
/ 02 апреля 2020

У меня проблема с анализом строки, ассоциированной с ключом детали. ключ значения имеет строку дубликатов, которая должна быть извлечена как пара ключ / значение.

Это образец json данных

{
  "response": {
   "client_log": {
      "data": [
        {
          "login": "AAAAAAAAAAAAAA",
          "state": "MC",
          "details": "Please find report below:\r\n\r\n------Report Information------\r\n\r\nEmail Id: user1@gmail.com\r\nServ Id: 112233\r\nProd Num: 11111\r\nProd Unit: Super-A\r\nProd Type: type-A\r\n,Serv Id: 445566\r\nProd Num: 22222\r\nProd Unit: Super-C\r\nProd Type: type-A\r\n,Serv Id: 003377\r\nProd Num: 123456\r\nProd Unit: Super-B\r\nProd Type: type-X\r\nState: LONDON\r\nCity: LONDON\r\n\r\n------Service Information------\r\n\r\nUser Name: John Clark\r\nMobile Number: 000111222\r\n\r\n------Reported Form------\r\n\r\nForm-1: zzzzz\r\nType: 111\r\n\r\nRemarks: Remarks 123.",
          "log_number": "1"
        },
        {
          "login": "BBBBBBBBBBBBB",
          "state": "XX",
          "details": "Please find report below:\r\n\r\n------Report Information------\r\n\r\nEmail Id: user2@gmail.com\r\nServ Id: 767878\r\nProd Num: 34689\r\nProd Unit: Super-B\r\nProd Type: type-B\r\n,Serv Id: 128900\r\nProd Num: 13689\r\nProd Unit: Super-A\r\nProd Type: type-B\r\n,Serv Id: 96333\r\nProd Num: 0011321\r\nProd Unit: Super-C\r\nProd Type: type-C\r\nState: State2\r\nCity: City2\r\n\r\n------Service Information------\r\n\r\nUser Name: Marry\r\nMobile Number: 982130989\r\n\r\n------Reported Form------\r\n\r\nForm-1: xxxxxx\r\nType: 222\r\n\r\nRemarks: Remarks 456.",
          "log_number": "1"
        }
      ],
      "query": "13"
    },
    "response_time": "0.723494",
    "transaction_id": "909122",
    "transaction_status": "OK"

  }
}

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

"details": "Please find report below:\r\n\r\n------Report Information------\r\n\r\nEmail Id: user1@gmail.com\r\nServ Id: 112233\r\nProd Num: 11111\r\nProd Unit: Super-A\r\nProd Type: type-A\r\n,Serv Id: 445566\r\nProd Num: 22222\r\nProd Unit: Super-C\r\nProd Type: type-A\r\n,Serv Id: 003377\r\nProd Num: 123456\r\nProd Unit: Super-B\r\nProd Type: type-X\r\nState: LONDON\r\nCity: LONDON\r\n\r\n------Service Information------\r\n\r\nUser Name: John Clark\r\nMobile Number: 000111222\r\n\r\n------Reported Form------\r\n\r\nForm-1: zzzzz\r\nType: 111\r\n\r\nRemarks: Remarks 123.",

получил дубликаты ключей, например, ключи 'Prod Num', Prod Unit 'и Prod Type' в приведенном выше примере ключи появились дважды.

Когда я читал файл, он не вернул все требуемые ключи в «деталях» ... пример вывода следующий:

{
          'city': 'LONDON',
          'login': 'AAAAAAAAAAAAAA',
          'state': 'MC',
          'details': 'Please find report below:\r\n\r\n------Report Information------\r\n\r\nEmail Id: user1@gmail.com\r\n**Serv Id: 112233\r\nProd Num: 11111\r\nProd Unit: Super-A\r\nProd Type: type-A\r\n,Serv Id: 445566\r\nProd Num: 22222\r\nProd Unit: Super-C\r\nProd Type: type-A\r\n,Serv Id: 003377\r\nProd Num: 123456\r\nProd Unit: Super-B\r\nProd Type: type-X**\r\nState: LONDON\r\nCity: LONDON\r\n\r\n------Service Information------\r\n\r\nUser Name: John Clark\r\nMobile Number: 000111222\r\n\r\n------Reported Form------\r\n\r\nForm-1: zzzzz\r\nType: 111\r\n\r\nRemarks: Remarks 123.',
          'log_number': '1',
          'department': 'Sales',
          'staff_id': 'S123',
          'staff_name': 'EricY',
          'timestamp': '2020-02-27 15:57:24',
          'Email_Id': 'user1@gmail.com',
          'Serv_Id': '112233',
          'Prod_Num': '123456',
          'Prod_Unit': 'Super-B',
          'Prod_Type': 'type-X',
          ',Serv_Id': '003377',
          'State': 'LONDON',
          'City': 'LONDON',
          'User_Name': 'John Clark',
          'Mobile_Number': '000111222',
          'Form-1': 'zzzzz',
          'Type': '111',
          'Remarks': 'Remarks 123.'
        },

Если вы видите вывод сверху, я получил

'Serv_Id': '112233' , 'Prod_Num': '123456', 'Prod_Unit': 'Super-B', 'Prod_Type': 'type-X' and ',Serv_Id': '003377' 

из-за того же Ключи он заменит значения каждого ключа с последним / последним значениями ... в этом случае в соответствии с приведенными ниже значениями ... более ранние значения заменяются.

Prod Num: 123456, Prod Unit: Super-B and Prod Type: type-X after key ',Serv_Id': '003377'

Я думаю, что это из-за дубликатов ключи. В некотором словаре также имеется более одного ключа 'Serv_Id' ... и это будет означать, что в списке словарей будет больше дубликатов Prod Num, Prod Unit и Prod Type, и их нельзя будет правильно прочитать как пару ключей. Те же ключи будут заменены на последние значения ...

Как побороть этот дубликат ключа? возможно, чтобы изменить имя ключа на другое имя, чтобы сделать его уникальным.

Я ожидаю что-то вроде вывода, как показано ниже

{
          'city': 'LONDON',
          'login': 'AAAAAAAAAAAAAA',
          'state': 'MC',
          'details': 'Please find report below:\r\n\r\n------Report Information------\r\n\r\nEmail Id: user1@gmail.com\r\nServ Id: 112233\r\nProd Num: 11111\r\nProd Unit: Super-A\r\nProd Type: type-A\r\n,Serv Id: 445566\r\nProd Num: 22222\r\nProd Unit: Super-C\r\nProd Type: type-A\r\n,Serv Id: 003377\r\nProd Num: 123456\r\nProd Unit: Super-B\r\nProd Type: type-X\r\nState: LONDON\r\nCity: LONDON\r\n\r\n------Service Information------\r\n\r\nUser Name: John Clark\r\nMobile Number: 000111222\r\n\r\n------Reported Form------\r\n\r\nForm-1: zzzzz\r\nType: 111\r\n\r\nRemarks: Remarks 123.',
          'log_number': '1',
          'department': 'Sales',
          'staff_id': 'S123',
          'staff_name': 'EricY',
          'timestamp': '2020-02-27 15:57:24',
          'Email_Id': 'user1@gmail.com',
          'Serv_Id': '112233', ------>1st Serv_Id 
          'Prod_Num_1': '111111',--->1st prod_num with new keyname
          'Prod_Unit_1': 'Super-A', --->1st prod_unit with new keyname
          'Prod_Type_1': 'type-A', --->1st prod_type with new keyname
          ',Serv_Id': '003377',------>2nd Serv_Id with new keyname
          'Prod_Num_2': '123456',--->2nd prod_num with new keyname
          'Prod_Unit_2': 'Super-B', --->2nd prod_unit with new keyname
          'Prod_Type_2: 'type-X', ---> 2nd prod_type with new keyname
          'State': 'LONDON',
          'City': 'LONDON',
          'User_Name': 'John Clark',
          'Mobile_Number': '000111222',
          'Form-1': 'zzzzz',
          'Type': '111',
          'Remarks': 'Remarks 123.'
        },

***The ',Serv_Id' key can be more than one. ***

Ниже приведен скрипт, который я использовал для чтения файла и извлечения деталей к ключевой паре.

for entry in mydata['response']['client_log']['data']:
    parsed_details = {}
    for line in entry['details'].split('\r\n'):
        try:
            key, value = line.split(': ', maxsplit=1)
            parsed_details[key] = value
            parsed_details = { x.translate({32:'_'}) : y  
                for x, y in parsed_details.items()}
        except ValueError:
            pass

    entry.update(parsed_details)

Я ценю вашу помощь в этом вопросе. Пожалуйста, ведите меня. Спасибо

1 Ответ

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

Редактировать: Я написал это довольно поздно прошлой ночью и вернулся, чтобы внести несколько правок.

В этом случае вы можете использовать некоторые простые манипуляции со строками, чтобы делать то, что вы надеетесь сделать. Я внес некоторые изменения в ваш исходный код и выделил различия в комментариях к коду.

import json

myfile = 'sample.json'

with open(myfile, 'r') as f:
   mydata = json.load(f)

for entry in mydata['response']['client_log']['data']:
    my_keys = []
    my_values = []
    for i, line in enumerate(entry['details'].split('\r\n')):
        # If we find ": " in the line, then it contains a key, value pair
        if ": " in line:
            # Strip the line of whitespace and "," and then split it on ":"
            line = line.strip().strip(",").split(":")
            # Add the key to the keys array, and add the value to the values
            my_keys.append(line[0].replace(" ", "_"))
            my_values.append(line[1].strip())
    # Set an increment variable
    inc = 1
    parsed_details = {}
    key_str = ""
    # For each key and value in the keys and values
    for key, value in zip(my_keys, my_values):
        # If their are duplicate keys of the given key
        if my_keys.count(key) > 1:
            # Create a key_str to add onto the key
            key_str = "_{}".format(inc)
            key = key + key_str
            # If this key exists, increment the counter by 1
            if key in list(parsed_details.keys()):
                inc += 1
                # Strip the old key_str and add the new one
                key = key.strip(key_str)+ "_{}".format(inc)
        parsed_details[key] = value
    entry.update(parsed_details)
print(mydata)
...