在python中使用递归反转围绕值的字典

在python中使用递归反转围绕值的字典,python,algorithm,recursion,Python,Algorithm,Recursion,我有一个数据集,它遵循以下示例的结构: exampleset = { 'body' : { 'abdomen' : [{ 'arms' : { 'value' : 2, } },{ 'legs': { 'value' : 2, } }], 'hands' : {

我有一个数据集,它遵循以下示例的结构:

exampleset = {
    'body' : {
        'abdomen' : [{
            'arms' : {
                'value' : 2,
            }
        },{
            'legs': {
                'value' : 2,
            }
        }],
        'hands' : {
            'fingers' : {
                'value' : 5,
            }
        },
    }                
}
我正试图扭转这种局面,因此我得到了如下结果:

{'value': {'value1': {5: {'fingers': {'hands': {'body': {}}}}},
           'value2': {2: {'legs': {'abdomen': {'body': {}}}}},
           'value3': {2: {'arms': {'abdomen': {'body': {}}}}}},
}
(我希望我的括号匹配正确,但你明白了。)

我使用了两个递归函数来实现这一点,如下所示:

def recurse_find(data, values, count):
    global conf
    for key in data:
        for v in conf['value_names']:
            if key == v:
                values[v+str(count)] = {}
                values[v+str(count)][data[key]] = {}
                count += 1
                # originally just using this line:
                # values[data[key]] = {}
        if type(data[key]) is list:
            for i in data[key]:
                if type(i) is dict:
                    values = recurse_find(i, values, count)
                    values = add_new_level(values, key)
        elif type(data[key]) is dict:
            values = recurse_find(data[key], values, count)
            values = add_new_level(values, key)
    return values

def add_new_level(data, new_key):
    for key in data:
        if data[key] == {}:
            data[key][new_key] = {}
        else:
            data[key] = add_new_level(data[key], new_key)
    return data

conf = { "value_names": ["value"] }

for value in conf['value_names']:
    values[value] = recurse_find(exampleset, {}, 1)

print(values)
目前,我只得到一个正确返回的值,显然我希望它们都正确。最初我没有标记值(value1、value2等),但在执行此示例集时,我意识到,如果值相同,我只会得到一个!如果我删除value name键,它会找到所有的值(除非重复),但仍然不会返回正确的级别,因为它在循环时包含了一些其他值。我不关心值的顺序,只是它们的标签不同,所以我不会遗漏任何内容

当前结果:

{'value': {'value1': {5: {'fingers': {'hands': {'body': {}}}}}}}
我认为解决方案是包含一个非常简单的步骤,但我现在看不到,我已经花了太长时间研究这个问题。 谢谢你的帮助

编辑: 我进一步修改了递归函数,使
count
成为一个全局变量,并将
count=1
置于函数之外,解决了获取所有值的问题

我已经缩小了向
add\u new\u level
函数添加额外键的范围,但还没有找到如何更改它的方法

输出:

{'value': {'value1': {2: {'arms': {'abdomen': {'legs': {'abdomen': {'fingers': {'hands': {'body': {}}}}}}}}},
           'value2': {2: {'legs': {'abdomen': {'fingers': {'hands': {'body': {}}}}}}},
           'value3': {5: {'fingers': {'hands': {'body': {}}}}}}}

我已经稍微调整了您的输出类型,使包含“value1”“value2”等的字典。。。到一个数组。我认为这样更好,因为除非使用OrderedDict(来自collections包),否则它们的顺序将丢失,并且在任何情况下,数组都将非常容易地从索引0,1,2,3转换。。到val1、val2、val3等

res = {'value': []}
def revnest(inp, keys=[]):
    res2 = res['value']
    if type(inp) == list:
        inp = {i:j[i] for j in inp for i in j}
    for x in inp:
        if x == 'value':
            res2.append({inp[x]:{}})
            res2 = res2[-1][inp[x]]
            for y in keys[::-1]:
                res2[y] = {}
                res2 = res2[y]
        else:
            revnest(inp[x], keys+[x])

revnest(exampleset)
print res
根据您的示例集,打印:

{'value': [{2: {'legs': {'abdomen': {'body': {}}}}}, {2: {'arms': {'abdomen': {'body': {}}}}}, {5: {'fingers': {'hands': {'body': {}}}}}]}

? 为什么要创建词典?输出看起来相当笨拙。我是说我不知道你会怎么用它。我的猜测是一个列表会是一个更好的选择。它适用于我正在做的事情。很难解释,但层次结构有助于确定数据之间的关系,这对我很有用。我不知道之前的层次结构是什么,也不知道可能与值有关系的数据,我只知道我想要值,然后我可以通过检查它的分支来确定有用的信息。这是我能想到的得到我想要的结果的最简单、最快捷的方法。列表也是如此。最外层必须是dict。虽然我可以使用值列表,但它们的内容仍然必须是dict形式,除非我使用有序列表来维护数据进入的顺序,以准确了解它与值的关系。另外,我打算将其横向扩展,以便在我认为有用的情况下,可以记录每个级别的额外数据。我在这里给出了一个基本的示例数据集;真正的一个是相当广泛的。如果你提出了一个很好的解决方案,我的问题使用列表,请随时张贴它作为一个答案…;)这完美地解决了我的问题,非常感谢!我不知道您可以使用[-1](从末尾?)或键[:-1]功能为列表编制索引。学到了一些新东西很高兴我能帮忙。keys[::-1]与reversed(keys)相同,但有点像mathy:)嗯。我也不知道倒过来的钥匙。今天是知识的双重打击。数学从来都不坏!我一直在寻找不同的方法来实现解决方案,因为我还是Python的新手。我懂数学。这让我想起了Perl。Perl非常适合解决像您这样的问题。