首页 > 解决方案 > 从文本文件在 Python 中创建嵌套字典

问题描述

我对 Python3 中的嵌套字典有疑问。尝试了很多方法,但我仍然被程序的意外结果所困扰。文本文件包含以下信息:

SERVER01_X  
--------------------------------------------------
Tue May 07, 01:15 
--------------------------------------------------
MEMORY: ''

Value  Name
876    SWAP_MEMORY
180    BUFFER
1371   TOTAL

--------------------------------------------------
Tue May 07, 01:45 
--------------------------------------------------
MEMORY: ''

Value  Name
871    SWAP_MEMORY
187    BUFFER
1379   TOTAL


SERVER02_Y  
--------------------------------------------------
Tue May 07, 01:15 
--------------------------------------------------
MEMORY: ''

Value  Name
76    SWAP_MEMORY
80    BUFFER
371   TOTAL

--------------------------------------------------
Tue May 07, 01:45 
--------------------------------------------------
MEMORY: ''

Value  Name
71    SWAP_MEMORY
87    BUFFER
379   TOTAL

程序需要产生的预期输出如下:

server_information = {
     SERVER01: {
                 Tue May 07, 01:15 : {MEMORY: {SWAP_MEMORY: 876, BUFFER: 180, TOTAL: 1371}} 
                 Tue May 07, 01:45 : {MEMORY: {SWAP_MEMORY: 871, BUFFER: 180, TOTAL: 1379}}                 
                }      
     SERVER02 : {
                 Tue May 07, 01:15 : {MEMORY: {SWAP_MEMORY: 76, BUFFER: 80, TOTAL: 371}} 
                 Tue May 07, 01:45 : {MEMORY: {SWAP_MEMORY: 71, BUFFER: 87, TOTAL: 379}}                 
                }      
}


以下是我尝试过的程序:

 #!/usr/bin/python3

import re

def convert_tuple(tuple):
    string = ' '.join(tuple)
    return string

with open('file3.txt') as infile:
    answer = {}  # dictionary initialisation
    for line in infile:
        server_name = ''.join(re.findall(r'^(\w+)\_\w{1}',line))
        # Tue May 07, 01:15
        dates = re.findall(r'^\w{3}\s+(\w{3})\s+(\d{2})\,\s+(\d{2}\:\d{2}).*',line)
        object_types = re.findall(r'(^\w+)\:.*',line)

        object_type_values = re.findall(r'^(\d+)\s+(\w+)',line)
        if server_name:
            key = server_name 
        for date in dates:
            date_converted = (convert_tuple(date))
        for object_type in object_types:
            obj_type = object_type
        for object_type_value, object_type_name in object_type_values:
            answer[key] = {date_converted: {obj_type: {object_type_name: {object_type_value}}}}
            print(answer)

我的程序的输出如下:

{'SERVER01': {'May 07 01:15': {'MEMORY': {'SWAP_MEMORY': {'876'}}}}}
{'SERVER01': {'May 07 01:15': {'MEMORY': {'BUFFER': {'180'}}}}}
{'SERVER01': {'May 07 01:15': {'MEMORY': {'TOTAL': {'1371'}}}}}
{'SERVER01': {'May 07 01:45': {'MEMORY': {'SWAP_MEMORY': {'871'}}}}}
{'SERVER01': {'May 07 01:45': {'MEMORY': {'BUFFER': {'187'}}}}}
{'SERVER01': {'May 07 01:45': {'MEMORY': {'TOTAL': {'1379'}}}}}
{'SERVER01': {'May 07 01:45': {'MEMORY': {'TOTAL': {'1379'}}}}, 'SERVER02': {'May 07 01:15': {'MEMORY': {'SWAP_MEMORY': {'76'}}}}}
{'SERVER01': {'May 07 01:45': {'MEMORY': {'TOTAL': {'1379'}}}}, 'SERVER02': {'May 07 01:15': {'MEMORY': {'BUFFER': {'80'}}}}}
{'SERVER01': {'May 07 01:45': {'MEMORY': {'TOTAL': {'1379'}}}}, 'SERVER02': {'May 07 01:15': {'MEMORY': {'TOTAL': {'371'}}}}}
{'SERVER01': {'May 07 01:45': {'MEMORY': {'TOTAL': {'1379'}}}}, 'SERVER02': {'May 07 01:45': {'MEMORY': {'SWAP_MEMORY': {'71'}}}}}
{'SERVER01': {'May 07 01:45': {'MEMORY': {'TOTAL': {'1379'}}}}, 'SERVER02': {'May 07 01:45': {'MEMORY': {'BUFFER': {'87'}}}}}
{'SERVER01': {'May 07 01:45': {'MEMORY': {'TOTAL': {'1379'}}}}, 'SERVER02': {'May 07 01:45': {'MEMORY': {'TOTAL': {'379'}}}}}

标签: python-3.x

解决方案


我知道这不是最漂亮的答案,但它确实有效。

我没有触及任何正则表达式,但我添加了一个部分来检查字典中是否已经存在值。根据是否有值和键,我可以添加相关的值。

import re


def convert_tuple(tuple):
    string = ' '.join(tuple)
    return string


with open('file3.txt') as infile:
    answer = {}  # dictionary initialisation
    for line in infile:
        server_name = ''.join(re.findall(r'^(\w+)\_\w{1}', line))
        # Tue May 07, 01:15
        dates = re.findall(r'^\w{3}\s+(\w{3})\s+(\d{2})\,\s+(\d{2}\:\d{2}).*', line)
        object_types = re.findall(r'(^\w+)\:.*', line)

        object_type_values = re.findall(r'^(\d+)\s+(\w+)', line)
        if server_name:
            key = server_name
        for date in dates:
            date_converted = (convert_tuple(date))
        for object_type in object_types:
            obj_type = object_type
        for object_type_value, object_type_name in object_type_values:
            if answer.get(key):
                if answer[key].get(date_converted):
                    if answer[key][date_converted].get(obj_type):
                        if not answer[key][date_converted][obj_type].get(object_type_name):
                            answer[key][date_converted][obj_type][object_type_name] = object_type_value
                    else:
                        answer[key][date_converted][object_type] = {object_type_name: object_type_value}
                else:
                    answer[key][date_converted] = {obj_type: {object_type_name: object_type_value}}
            else:
                answer[key] = {date_converted: {obj_type: {object_type_name: object_type_value}}}

import json

parsed = json.loads(str(answer).replace("'", '"'))
print(json.dumps(parsed, indent=4))

这输出:

{
    "SERVER01": {
        "May 07 01:15": {
            "MEMORY": {
                "SWAP_MEMORY": "876",
                "BUFFER": "180",
                "TOTAL": "1371"
            }
        },
        "May 07 01:45": {
            "MEMORY": {
                "SWAP_MEMORY": "871",
                "BUFFER": "187",
                "TOTAL": "1379"
            }
        }
    },
    "SERVER02": {
        "May 07 01:15": {
            "MEMORY": {
                "SWAP_MEMORY": "76",
                "BUFFER": "80",
                "TOTAL": "371"
            }
        },
        "May 07 01:45": {
            "MEMORY": {
                "SWAP_MEMORY": "71",
                "BUFFER": "87",
                "TOTAL": "379"
            }
        }
    }
}

如果你想要这个更整洁,我相信https://codereview.stackexchange.com/上的人不会介意帮助你。


推荐阅读