对变量进行递归查找

2024-05-03 08:28:18 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个字典列表,可以为解释器模拟一堆环境。例如,在第一个环境中,我可能定义了值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

我想知道是否可以将其压缩为一个递归定义,例如:

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

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


Tags: theselfenvnonegetif定义环境
2条回答

该模式看起来不错,不过我建议删除env_堆栈的默认值,因为它总是会导致异常。有一个总是无效的默认参数是没有意义的,所以除非有理由保留它,否则我会删除它

干得好

来自collections模块的ChainMap类就是为此而设计的(docs link)。如果env_stackChainMap的一个实例,那么您只需编写env_stack[k]即可从堆栈顶部最近的字典中获取键k的值

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

相关问题 更多 >