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

Hierarchical Data Traversal and Representation in Python

我在 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: {
            ...
        },
    }
}

从心理上讲,我只是没有建立编程连接来遍历一个级别,通过推动到下一个级别来遵循父代码以构建子级,然后返回我来的方式并继续下一个代码,同时保持某种记录,记录我建立了哪些关系,哪些关系还没有建立,因此不会重复。并不是真的在寻找交给我的答案,而只是寻找一些解决这个问题的策略。似乎解决方案涉及递归,但我还必须保持一些状态以引用上一级和下一级。

如有任何指导,我们将不胜感激。

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

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.

Python 3 实施@Delforge 的回答

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: {}},
}}