我已经看到有相当多的问题或多或少地解决了这个问题,但我还没有设法将它们应用到我的特定用例中,我已经挠头尝试了几天不同的解决方案
我有一个字典列表,它们的层次结构位置编码为一个索引编号字符串——我想使用这些索引将字典重新排列成嵌套的层次结构
以下是一些示例数据:
my_data = [{'id':1, 'text':'one', 'path':'1'},
{'id':2, 'text':'two', 'path':'3.1'},
{'id':3, 'text':'three', 'path':'2.1.1'},
{'id':4, 'text':'four', 'path':'3.2.1'},
{'id':5, 'text':'five', 'path':'2.1.2'},
{'id':6, 'text':'six', 'path':'3.2.2'},
{'id':7, 'text':'seven', 'path':'2'},
{'id':8, 'text':'eight', 'path':'3'},
{'id':9, 'text':'nine', 'path':'3.2'},
{'id':10, 'text':'ten', 'path':'2.1'}]
以下是我努力实现的目标:
result = {1:{'id':1, 'text':'one', 'path':'1'},
2:{'id':7, 'text':'seven', 'path':'2', 'children':{
1:{'id':10, 'text':'ten', 'path':'2.1', 'children':{
1:{'id':3, 'text':'three', 'path':'2.1.1'},
2:{'id':5, 'text':'five', 'path':'2.1.2'}
}}}},
3:{'id':8, 'text':'eight', 'path':'3', 'children':{
1:{'id':2, 'text':'two', 'path':'3.1'},
2:{'id':9, 'text':'nine', 'path':'3.2', 'children':{
1:{'id':4, 'text':'four', 'path':'3.2.1'},
2:{'id':6, 'text':'six', 'path':'3.2.2'}
}}}}
}
由于各个数据字典的路径不以任何逻辑顺序出现,因此我在整个过程中使用字典,而不是字典列表,因为这允许我在结构中创建“空”空间。我真的不想依赖于对初始列表中的词典重新排序
这是我的密码:
#%%
class my_dict(dict):
def rec_update(self, index, dictObj): # extend the dict class with recursive update function
"""
Parameters
----------
index : list
path to dictObj.
dictObj : dict
data object.
Returns: updates the dictionary instance
-------
None.
"""
pos = index[0]
index.pop(0)
if len(index) != 0:
self.update({pos : {'children' : {self.rec_update(index, dictObj)}}})
else:
self.update({pos : dictObj})
#%%
dataOut = my_dict() #create empty dictionary to receive result
dataOut.clear()
# dictObj = my_data[0] # for testing
# dictObj = my_data[1]
for dictObj in my_data:
index = dictObj.get('path').split(".") # create the path list
dataOut.rec_update(index, dictObj) # place the current data dictionary in the hierarchy
代码的问题是类定义self.rec_update(index, dictObj)
中的嵌套函数调用的结果不是“children”键的值。这是因为我没有正确理解self
的范围吗
我在测试期间注意到,如果我对my_data
的单个元素运行dataOut.rec_update(index, dictObj)
调用,例如dictObj = my_data[1]
,控制台范围中的索引列表变量会被修改,这是出乎意料的,因为我认为rec_update()
函数有它自己独特的范围
我想我可以看到一个更进一步的bug,其中“children”元素将被覆盖,但我还没有到那个阶段
我欢迎任何能让我走上正轨的解释
这里有一个解决方案,你应该能够适应你的需要。它只是一个将
my_data
转换为result
的独立函数:当被称为:
它给
result
一个值:请注意,Python3字典维护添加元素的顺序,因此从这个意义上讲,构建的树在每个级别都由相应的路径组件“排序”
还请注意,原始源代码列表及其包含的词典不会因此函数而改变
我想我已经破解了!在这个过程中我学到了很多。(我希望如此——我已经打开了至少24个so选项卡,6个doc.python.org选项卡,可能还有20个其他选项卡——所以这是一次集体努力!)
下面是一个递归函数,用于创建所需的嵌套数据:
这是呼叫代码:
我仍然不明白为什么在调用代码-answers welcome:-)中对函数alter index中的
index
进行更改但是我确实发现我不能在我的
my_dict
类定义中用__copy__()
函数重写dict.copy()
,因此dictTemp = my_dict(self[pos]['children'])
而不是dictTemp = self[pos]['children'].copy()
最后一个我仍然要解决的奇怪问题是:当我将它应用到我的生产数据时,我必须运行它两次
相关问题 更多 >
编程相关推荐