【问题标题】:Recursive function in nested dictionaries嵌套字典中的递归函数
【发布时间】:2026-02-13 01:55:02
【问题描述】:

我有这样的嵌套字典,其中键是函数{'Foo1': {'Foo2': {'value1': 0}, 'Foo3': {'value2': 1, 'value3': 1}}}

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

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

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

【问题讨论】:

  • 你能把你的字典机智键的实际例子发布为函数吗?
  • 由于字典是无序的,您的final value 也可能是Foo1(Foo3(1,1), Foo2(0)) - 这可能是完全不同的东西。
  • 感谢您的评论,但这里的顺序并不重要。
  • 可能和你写的一样。 final_value 不会改变@ChristianKönig
  • @AmeyDahale 例如:dct = {'any': {'none': {'value1': 0}, 'all': {'value2': 1, 'value3': 1} }}

标签: python recursion


【解决方案1】:

对于您的特定情况,我建议使用映射到 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],因为它们是位于数据根目录的单个函数。如果您的数据始终只有一个根函数,您可能希望将 parse 称为 output = parse(data)[0]

【讨论】:

  • 谢谢! "None" 不适用于列表(not([0]) 返回 False,但应该返回 True),但我会修复它。