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

时间:2020-07-01 15:27:42

标签: python list dictionary nested

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

前三个可以正常工作,但是当我对层次结构有更多步骤时,我无法获得理想的回报。我只是在学习Python,所以如果有什么建议可以改善我的丑陋代码,我将不胜感激。

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

以下是我正在尝试的3个示例。前两个是正确的,但它们仅适用于步骤0和步骤1。 / p>

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

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

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

对于给您带来的任何困惑,我深表歉意。

#!/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")

这是当前输出。

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

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

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

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

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

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

我正在尝试使第三个输出看起来像这样。

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

1 个答案:

答案 0 :(得分:0)

这是一个解决方案。请注意,除了实际结果外,还返回从列表中消耗了多少物品。当然,您也可以忽略它。

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']]]})
相关问题