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