嵌套字典中的递归函数

时间:2017-05-26 11:25:03

标签: python recursion

我已经嵌套了这样的词,其中键是函数{'Foo1': {'Foo2': {'value1': 0}, 'Foo3': {'value2': 1, 'value3': 1}}}

我想编写一个递归函数,它必须计算最终值。在这种情况下,它将是:

final_value = Foo1(Foo2(0), Foo3(1,1))

如果有人帮我提供建议,我将非常高兴。

1 个答案:

答案 0 :(得分:0)

对于您的特定情况,我建议使用允许函数名称的显式白名单,该函数名称映射到Python中的函数(请参阅下面代码中的WHITELIST)。如果您尝试解析不受信任的数据,这可以缓解许多可能令人讨厌的安全问题。它还处理您的"none"要求,该要求不会映射到Python中的实际函数。

代码的重要部分是parse函数。它以递归方式遍历输入数据,并将每个键分类为函数或变量名。如果它是一个函数,它会使用该键的值调用该函数。否则,它只使用该值。无论哪种方式,此信息都会保存到results,并以递归方式传递给调用者。

请注意,此实现甚至不会开始尝试处理格式错误的输入。我强烈建议在parse块中包装try ... catch以优雅地处理错误输入。

data = {
    'any': {
        'none': {'value1': 0},
        'sum': {'value2': 0, 'value3': 1}
    }
}

# This can be expanded to include other functions that aren't built-in.
# Note that "none" is special because "not" isn't actually a function.
WHITELIST = {
    "any": any,
    "all": all,
    "sum": sum,
    "none": lambda x: not x
    "10": is_10 # Sample additional function you could add.
}

def is_10(values):
    return sum(values) == 10

def parse(data):
    results = []
    # Uncomment the next line if you're on Python 2.
    # for key, value in d.iteritems():
    # Leave this line if you're on Python 3.
    for key, value in data.items():
        if key in WHITELIST:
            # This is a function.
            function = WHITELIST[key]
            args = parse(value)
            results.append(function(args))
        else:
            # This is a value, so the name doesn't actually matter.
            results.append(value)
    return results

print(parse(data))

对于代码顶部的示例,它会打印[True],因为它们是数据根目录下的单个函数。如果您的数据始终具有单个根函数,则可能需要将解析称为output = parse(data)[0]