Python中的分层数据遍历和表示

时间:2017-12-21 23:09:39

标签: python python-3.x nested hierarchical-data

我有一些存储在OrderedDict中的分层代码,其中的键对应于层次结构的级别和每个级别的代码列表,每个子级别与父级别的代码有关系:

from collections import OrderedDict

codes_ord_dict = OrderedDict([
    (2, [11]), 
    (3, [111, 112]), 
    (4, [1111, 1112, 1113, 1114, 1119, 1121, 1122, 1123, 1124, 1125, 1129])
])

我试图从这个表单中获取一个例如嵌套字典或这些代码的树表示,前者类似于:

codes_dict = {
    11: {
        111: {
            1111: {
               ... 
            },
            1112: {
                ...
            },
            1113: {
                ...
            },
            ...
        },
        112: {
            ...
        },
    }
}

在心理上,我只是没有使编程连接遍历一个级别,按照父代码推进到下一级别构建子级,然后返回我的方式并继续下一个代码,同时保持一些关于我建立的关系和我没有建立的关系的记录,所以没有重复。不是真的在寻找给我的答案,而只是一些如何处理这个问题的策略。似乎解决方案将涉及递归,但我还必须保持一些状态来引用先前的级别和下一级别。

任何指导都将不胜感激。

2 个答案:

答案 0 :(得分:1)

根据您的数据结构,每个代码都包含有关其父项的信息。因此,您可以先编写一个映射给定代码层次结构的函数:

def code_to_map(code):
    codestr = str(code)
    codemap = [int(codestr[:i]) for i in range(2, len(codestr) + 1)]
    return codemap

print(code_to_map(1111))
# [11, 111, 1111]

然后,这是一个创建嵌套字典的简单实现:

# create a dictionary to store results

d = {}

# iterate through code list in your ordered dict

for code_list in codes_ord_dict.itervalues():

    # iterate through code in code list

    for code in code_list:

        # initiate new code
        lvl = 0
        parent = d

        # get the code map
        code_map = code_to_map(code)

        # while the dictionary contains the key in the code map
        # child is set as parent and level is incremented

        while parent.has_key(code_map[lvl]):

            parent = parent.get(code_map[lvl])

            lvl += 1

        # Add the new dictionary as the code map does not exist

        parent[code_map[lvl]] = {}

print(d)
# {
#   11: {
#       111: {
#           1111: {},
#           1112: {},
#           1113: {},
#           1114: {},
#           1119: {}
#       },
#       112: {
#           1121: {},
#           1122: {},
#           1123: {},
#           1124: {},
#           1125: {},
#           1129: {}
#       }
#   }
# }

这是一个天真的实现,因为它是高度冗余的,但你得到了逻辑。实际上,您不需要遍历整个code_order_dict,而只需要遍历最高级别的代码值(您的叶code_order_dict[4]),因为它们包含有关整个字典树的信息。

请注意,我在python 2.7中运行此代码,但我想它应该在python 3下运行。

答案 1 :(得分:0)

@ Delforge的答案的Python 3实现

def code_to_map(code):
    code_str = str(code)
    code_map = [int(code_str[:i]) for i in range(2, len(code_str) + 1)]
    return code_map

d = {}
for code_list in code_ord_dict.values():
    for code in code_list:
        lvl = 0
        parent = d
        code_map = code_to_map(code)
        while code_map[lvl] in parent:
            parent = parent.get(code_map[lvl])
            lvl += 1
        parent[code_map[lvl]] = {}



from pprint import pprint
pprint(d)

输出片段,扩展名为6级(7位)

{11: {111: {1111: {11111: {111110: {}},
                   11112: {111120: {}},
                   11113: {111130: {}},
                   11114: {111140: {}},
                   11115: {111150: {}},
                   11116: {111160: {}},
                   11119: {111191: {}, 111199: {}}},
            1112: {11121: {111211: {}, 111219: {}}},
            1113: {11131: {111310: {}},
                   11132: {111320: {}},
                   11133: {111331: {},
                           111332: {},
                           111333: {},
                           111334: {},
                           111335: {},
                           111336: {},
                           111339: {}}},
            1114: {11141: {111411: {}, 111419: {}},
                   11142: {111421: {1114211: {}, 1114212: {}, 1114219: {}},
}}