使用递归来反转python

时间:2016-02-25 12:33:38

标签: python algorithm recursion

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

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': {'value1': {5: {'fingers': {'hands': {'body': {}}}}}}}

我认为解决方案是包含一个非常简单的步骤,但我目前无法看到它,而且我已经花了太长时间看这个。 任何帮助表示赞赏。

编辑:

我通过更改递归函数使count成为一个全局变量并在函数外部count=1来解决所有值的问题,从而进一步了解。

我已经缩小了对add_new_level功能添加额外键的范围,但尚未找到如何更改它。

输出:

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

1 个答案:

答案 0 :(得分:1)

我稍微调整了你的输出类型,使包含'value1''value2'等字典的字典成为一个数组。我相信这更好,因为除非使用OrderedDict(来自集合包),否则它们的顺序将会丢失,并且在任何情况下,数组都很容易从索引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

给出了你的exampleset,打印:

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