从列表列表创建dict

Bry*_*ind 16 python dictionary file

我有一个我读过的文本文件.这是一个日志文件,因此它遵循特定的模式.我最终需要创建一个JSON,但是从研究这个问题开始,一旦它出现在dict中,它将是一个使用json.loads()或者问题json.dumps().

下面是文本文件的示例.

INFO:20180606_141527:submit:is_test=False
INFO:20180606_141527:submit:username=Mary
INFO:20180606_141527:env:sys.platform=linux2
INFO:20180606_141527:env:os.name=ubuntu
Run Code Online (Sandbox Code Playgroud)

我最后寻找的字典结构是

{
  "INFO": {
    "submit": {
      "is_test": false,
      "username": "Mary"
    },
    "env": {
      "sys.platform": "linux2",
      "os.name": "ubuntu"
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

我暂时忽略每个列表中的时间戳信息.

这是我正在使用的代码的片段,

import csv
tree_dict = {}
with open('file.log') as file:
    for row in file:
        for key in reversed(row.split(":")):
            tree_dict = {key: tree_dict}
Run Code Online (Sandbox Code Playgroud)

这导致不希望的输出,

{'INFO': {'20180606_141527': {'submit': {'os.name=posix\n': {'INFO': {'20180606_141527': {'submit': {'sys.platform=linux2\n': {'INFO': {'20180606_141527': {'submit': {'username=a227874\n': {'INFO': {'20180606_141527': {'submit': {'is_test=False\n': {}}}}}}}}}}}}}}}}}
Run Code Online (Sandbox Code Playgroud)

我需要动态填充dict,因为我不知道实际的字段/键名.

Dru*_*lan 13

with open('demo.txt') as f:
    lines = f.readlines()

dct = {}

for line in lines:
    # param1 == INFO
    # param2 == submit or env
    # params3 == is_test=False etc.
    param1, _, param2, params3 = line.strip().split(':')

    # create dct[param1] = {} if it is not created
    dct.setdefault(param1, {})

    # create dct[param1][param2] = {} if it is no created
    dct[param1].setdefault(param2, {})

    # for example params3 == is_test=False
    # split it by '=' and now we unpack it
    # k == is_test
    # v == False
    k, v = params3.split('=')

    # and update our `dict` with the new values
    dct[param1][param2].update({k: v})

print(dct)
Run Code Online (Sandbox Code Playgroud)

产量

{
'INFO': {
    'submit': {
        'is_test': 'False', 'username': 'Mary'
        }, 
    'env': {
        'sys.platform': 'linux2', 'os.name': 'ubuntu'
        }
    }
}  
Run Code Online (Sandbox Code Playgroud)


DYZ*_*DYZ 7

这是Python中的递归似乎是合适且有用的罕见情况之一.以下函数将a添加valued由以下列表指定的分层字典keys:

def add_to_dict(d, keys, value): 
    if len(keys) == 1: # The last key
        d[keys[0]] = value
        return
    if keys[0] not in d:
        d[keys[0]] = {} # Create a new subdict
    add_to_dict(d[keys[0]], keys[1:], value)
Run Code Online (Sandbox Code Playgroud)

该函数适用于任意深度的字典.剩下的就是调用函数:

d = {}
for line in file:
    keys, value = line.split("=")
    keys = keys.split(":")
    add_to_dict(d, keys, value.strip())
Run Code Online (Sandbox Code Playgroud)

结果:

{'INFO': {'20180606_141527': {
                       'submit': {'is_test': 'False', 
                                  'username': 'Mary'}, 
                       'env': {'sys.platform': 'linux2', 
                               'os.name': 'ubuntu'}}}}
Run Code Online (Sandbox Code Playgroud)

您可以修改代码以排除某些级别(如时间戳).