将多个列表转换为嵌套字典

时间:2018-10-10 19:44:49

标签: 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]] = []

2 个答案:

答案 0 :(得分:1)

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

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替换为空列表,以避免该问题。

答案 1 :(得分:0)

您可以在循环中使用dict.setdefault方法来构建嵌套字典。我将使用pprint模块来显示输出。请注意,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': []}}}}}