将多行slashdelimited字符串转换为嵌套字典

2024-09-29 23:25:54 发布

您现在位置:Python中文网/ 问答频道 /正文

abc/pqr123/xy2/yes//T  
abc/pqr245/kl3/yes//T  
abc/ijk123/op5/yes//T  
abc/pqr245/kl4/yes//T

这些是我要转换为嵌套字典的输入值 abc,pqr123,xy2,是,T 表示产品的名称

我的输出应该如下所示:

{"abc":{"pqr123":{"xy2":{"yes":{"T":[]}},"pqr245":"kl3":{"yes":{"T": 
[]}},"kl4":{"yes":{"T":[]}},"ijk123":{"op5":{"yes":{"T":[]}}}  

所以我需要一个包含所有唯一值的嵌套字典,字典的最后一个键应该有一个空列表值

下面是我生成所需输出的代码片段,但我希望更动态地执行此操作,以便它更适合我 如果输入的长度增加或减少。请告诉我是否有更好的解决方案

data_dict={}
for item in meta_line.split(','):
    item = item.replace('//','/')
    item = str(item) 
    item = item.split('/')
    if item[0] == "":
       continue  

    if item[0] not in data_dict.keys():
       data_dict[item[0]] = {}
    if item[1] not in data_dict[item[0]].keys():
       data_dict[item[0]][item[1]] = {}
    if item[2] not in data_dict[item[0]][item[1]].keys():
       data_dict[item[0]][item[1]][item[2]] = {}
    if item[3] not in data_dict[item[0]][item[1]][item[2]].keys():
       data_dict[item[0]][item[1]][item[2]][item[3]] = {}
    if item[4] not in data_dict[item[0]][item[1]][item[2]][item[3]].keys():
       data_dict[item[0]][item[1]][item[2]][item[3]][item[4]] = []

Tags: indataif字典notkeysitemdict
2条回答

你可能想要一些不依赖于大量嵌套括号的东西。使用对可变对象的引用可以很好地解决这个问题

meta_line = 'abc/pqr123/xy2/yes//T,abc/pqr245/kl3/yes//T,abc/ijk123/op5/yes//T,abc/pqr245/kl4/yes//T'

data = dict()
for item in meta_line.split(','):
    dref = data
    dict_tree = item.strip().replace('//', '/').split('/')
    for i, val in enumerate(dict_tree):
        if val in dref:
            pass
        elif i != len(dict_tree) - 1:
            dref[val] = dict()
        elif i == len(dict_tree) - 1:
           dref[val] = list()
        dref = dref[val]

内部循环的每次迭代都会将引用dref向下移动一个级别,然后在外部循环的每次迭代中重置它。最后,data应该保存嵌套的dict

编辑:对不起,我刚刚注意到您希望最后一级是列表。这是该问题的一种解决方案,但不是最好的(如果在稍后的数据输入想要成为dict的位置有一个列表,则会产生错误)。我可能会选择构建我的嵌套dict,然后用空列表递归地替换任何空dict,以避免这个问题

可以在循环中使用^{}方法来构建嵌套字典。我将使用^{}模块显示输出。注意pprint.pprint在计算输出之前对字典键进行排序

from pprint import pprint

data = '''\
abc/pqr123/xy2/yes//T
abc/pqr245/kl3/yes//T
abc/ijk123/op5/yes//T
abc/pqr245/kl4/yes//T
'''.splitlines()

nested_dict = {}

for row in data:
    d = nested_dict
    keys = [s for s in row.split('/') if s]
    for key in keys[:-1]:
        d = d.setdefault(key, {})
    d[keys[-1]] = []

pprint(nested_dict)

输出

{'abc': {'ijk123': {'op5': {'yes': {'T': []}}},
         'pqr123': {'xy2': {'yes': {'T': []}}},
         'pqr245': {'kl3': {'yes': {'T': []}}, 'kl4': {'yes': {'T': []}}}}}

相关问题 更多 >

    热门问题