繁体   English   中英

使用嵌套列表或来自 2 个列表的字典创建分层字典

[英]Creating a hierarchical dictionary with nested lists or dictionaries from 2 lists

我有 2 个清单。 第一个有数字,表示同一索引的另一个列表中的值属于层次结构的哪一部分。 我正在尝试获取理论上可以 go 到任意数量的步骤的动态代码。

前 3 个工作正常,但是当我有更多的层次结构步骤时,我无法获得完美的回报。 我只是在学习 Python 所以如果有任何建议可以改进我的丑陋代码,我将不胜感激。

第一个列表是一个包含数字的列表。 这些数字是层次结构中的步骤。 第二个列表将根据第一个列表在其共享索引处的步长值进行排序。

以下是我正在尝试的 3 个示例。 前 2 个是正确的,但它们仅适用于第 0 步和第 1 步。我正在尝试使代码适用于任何长度的列表和任何数字范围(接下来的步骤只能是 +/- 1)。

output 应该如下所示,使用显示步骤的第一个列表:

0
0
 1
 1
  2
   3
  2
  2
 1
0
 1
  2
   3
   3

我想将所有 0 步骤设置为第二个列表的相同索引值的字典。 该字典将包含嵌套列表或嵌套字典。 我不确定哪个是 go 的更好方法。

对于任何混淆,我深表歉意,并感谢您的帮助。

#!/bin/usr/env python

from pprint import pprint

print('\n')

list1 = [0, 1, 0, 1, 1]
lista = ['a','b','c', 'd', 'e']
dict = {}
for index, value in enumerate(lista):
  inc = 1
  if (list1[index] == 0):
     dict[value] = []
     try:
        while (list1[index + inc] > 0):
            dict[value].append(lista[index + inc])
            inc += 1
     except IndexError:
        pass

pprint(dict)

print('\n' + '#'*150 + "\n")

list2 = [0, 1, 1, 1, 1, 0, 1]
listb = ['a','b','c','d','e', 'f', 'g']
dict = {}
for index, value in enumerate(listb):
   inc = 1
    if (list2[index] == 0):
        dict[value] = []
        try:
            while (list2[index + inc] > 0):
                dict[value].append(listb[index + inc])
                inc += 1
        except IndexError:
            pass

pprint(dict)

print('\n' + '#'*150 + "\n")

list3 = [0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 2]
listc = ['a', 'b', 'c', 'd', 'e' ,'f' , 'g', 'h', 'i', 'j', 'k', 'l', 'm' ,'n' ,'o' , 'p', 'q' ,'r' ,'s', 't', 'u', 'v', 'w', 'x']

dict = {}
temp_dict = {}
for index, value in enumerate(listc):
    inc = 1
    if (list3[index] == 0):
       dict[value] = []
        try:
            while (list3[index + inc] > 0):
                if (list3[index + inc] < list3[index + (inc + 1)]):
                    dict[value].append([listc[index + inc]])
                elif (list3[index + inc] == list3[index + (inc + 1)]):
                    dict[value].append()
                inc += 1
        except IndexError:
            pass

pprint(dict)

print('\n' + '#'*150 + "\n")

这是当前的 output。

{'a': ['b'], 'c': ['d', 'e']}

######################################################################################################################################################

{'a': ['b', 'c', 'd', 'e'], 'f': ['g']}

######################################################################################################################################################

{'a': [['b']], 'v': [['w']]}

######################################################################################################################################################

我试图让第三个 output 看起来像这样。

{
'a': [ 'b', 
          [ 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u'], 
'v': [ 'w', 
          [ 'x']] 
}

这是一个解决方案。 请注意,除了实际结果之外,还会返回列表中消耗了多少项目。 如果你愿意,你当然可以忽略它。

def build_dict_from_lists(depth_list, item_list):
    if len(depth_list) != len(item_list):
        raise Exception("Canincompatible lengths")

    depth0 = depth_list[0]

    res = []
    next_index = 0
    while next_index < len(depth_list) and  depth_list[next_index] >= depth0:
        item = item_list[next_index]
        depth = depth_list[next_index]        
        if depth == depth0:
            res.append(item)
            next_index += 1
        else: 
            consumed, sub_res = build_dict_from_lists(depth_list[next_index:], item_list[next_index:])
            res.append(sub_res) 
            next_index += consumed 

    if depth0 == 0 and any(isinstance(x, list) for x in res): # switch the result from a dict to a list
        d = {}
        for inx in range(0, len(res), 2):
            key = res[inx]
            val = res[inx + 1]
            d[key] = val
        res = d 

    return next_index, res

一些测试来验证代码的正确性:

assert build_dict_from_lists([0, 0, 0], ["a", "b", "c"]) == (3, ['a', 'b', 'c'])

assert build_dict_from_lists([0, 1, 2], ["a", "b", "c"]) == (3, {'a': ['b', ['c']]})
assert build_dict_from_lists([0, 1, 2, 1, 2], ["a", "b", "c", "d", "e"]) == (5, {'a': ['b', ['c'], 'd', ['e']]})

list3 = [0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 2]
listc = ['a', 'b', 'c', 'd', 'e' ,'f' , 'g', 'h', 'i', 'j', 'k', 'l', 'm' ,'n' ,'o' , 'p', 'q' ,'r' ,'s', 't', 'u', 'v', 'w', 'x']

expected = {'a': 
[ 'b', 
          [ 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u']], 
'v': [ 'w', 
          [ 'x']] 
}
assert build_dict_from_lists(list3, listc) == (24, expected)

list4 = [0, 1, 1,     2,   2, 2,   2, 1,  2, 1, ] 
listd = ['a','b','c','d','e','f','g','h','i','j'] 
assert build_dict_from_lists(list4, listd) == (10, {'a': ['b', 'c', ['d', 'e', 'f', 'g'], 'h', ['i'], 'j']})

list5 = [0,   1,  1,  2,  2,  3,  3,  1,  1,  2,  2,  3] 
liste = ['a','b','c','d','e','f','g','h','i','j','k','l'] 
assert build_dict_from_lists(list5, liste) == (12, {'a': ['b', 'c', ['d', 'e', ['f', 'g']], 'h', 'i', ['j', 'k', ['l']]]})

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM