递归查找变量

我有一个字典列表来模拟解释器的一堆环境。例如,在第一个环境中我可能a=4定义了值,而在第二个环境中我可能已经b=3定义了,所以如果我这样做,env_get(a) + env_get(b)我应该得到7.

这是我目前所拥有的:

def env_get(self, k, env=None):
    v = None
    for env in reversed(self.envs): # as the "pop" is the equivalent of env[-1]
        v = env.get(k)
        if v: break
    if not v: raise AttributeError("Env does not contain '%s'" % k)
    return v

我想知道是否可以将其压缩为单个递归 def ,如下所示:

envs=[{'a':4},{'b':3}]
def get_env_recursive(k, env_stack=None):
    if not env_stack: raise AttributeError("Env does not contain '%s'" % k)
    return env_stack[-1].get(k) or get_env_recursive(k, env_stack[:-1])
>>> get_env_recursive('a',envs)+get_env_recursive('b',envs)
7

或者对单线发疯可以这样做:

>>> getr=lambda k,env_stack: env_stack[-1].get(k) or getr(k, env_stack[:-1]) if len(env_stack)>1 else env_stack[0][k]
>>> getr('a',envs)+getr('b',envs)
# 7

有没有更好的方法可以实现上述模式?

回答

模块中的ChainMapcollections就是为此目的而设计的(文档链接)。Ifenv_stackChainMapthen 的一个实例,您可以简单地编写env_stack[k]k从最接近堆栈顶部的字典中获取该键的值。

例如,您可以创建两个字典的堆栈,例如ChainMap({'a': 4}, {'b': 3}),其中第一个位于堆栈的顶部。更多使用示例可以在文档中找到。


以上是递归查找变量的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>