词典中的评价函数处理个别引用而不是词典理解

2024-10-04 11:32:13 发布

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

我有一个变量和值的列表,我用eval语句分配给它们

我正在尝试使用字典理解来匹配变量和计算值

当我对范围(0,10)中的I使用for循环时,其中len(ChosenVarNameList)=10:

 dictinitial = {}
 for i in range (0,len(ChosenVarNameList)):
        dictinitial[ChosenVarNameList[i]] = eval("%s" %ChosenVarNameList[i])

我可以编字典

当我引用单个索引时,我也可以看到字典正确填充(使用下面的代码)

      dictinitialnew = {ChosenVarNameList[0] : (eval("%s" 
      %ChosenVarNameList[0])).

但是,当我尝试字典理解时,就像下面的代码:

 dictinitialnew = {ChosenVarNameList[i] : (eval("%s" %ChosenVarNameList[i])) 
 for i in range (0,len(ChosenVarNameList)) }

我得到的代码是第一个变量名,比如说“Code1”没有定义。有没有一种方法可以通过字典理解来做到这一点,或者有没有一种方法可以让我绕过这个问题

提前谢谢


Tags: 方法代码in列表forlen字典定义
1条回答
网友
1楼 · 发布于 2024-10-04 11:32:13

您的问题是由于dict理解引入了嵌套作用域。出于最实际的目的,函数中的dict理解如下:

def myfunc(iterable, y):
    return {x: y for x in iterable}

实现方式非常类似于:

def myfunc(iterable, y):
    def _unnamed_func_(_unnamed_it_):
        retval = {}
        for x in _unnamed_it_:
            retval[x] = y  # Note: y is read from nested scope, not passed to inner func
        return retval
    return _unnamed_func_(iterable)  # Note: iterable passed as argument

与所有具有闭包作用域的函数一样,_unnamed_func_确定在定义嵌套作用域时需要哪些值,并将它们折叠到自己的闭包作用域中;在这种情况下,它需要来自嵌套作用域的y,而不是iterable(因为您迭代的第一个iterable作为参数传递给虚拟函数,而不是通过闭包作用域)

问题是,eval只使用本地和全局作用域的知识(以及所有代码所具有的内置作用域的隐式知识)执行;它不知道嵌套的作用域,因为您只通过eval引用变量,所以嵌套函数也不知道它需要这些变量

您可以用更简单的代码演示一般问题:

def outer(x):
    def inner():
        return eval('x')
    return inner

如果您尝试使用outer(1)()(并且在全局范围内没有x)运行它,它将随着NameError: name 'x' is not defined而消亡,因为x不是inner的闭包范围的一部分,并且在outer返回时它被立即丢弃。将eval('x')更改为x允许它工作(在本例中它返回1),因为没有eval的阻碍,inner会在定义时将x拉入其闭包范围,因此在以后运行inner时它是可用的

你的设计是一个糟糕的开始(eval不应该用于读取简单的变量名),dict理解只是让它完全崩溃

其原因是理解的语言定义是建立在生成表达式定义的基础上的,生成表达式必须用闭包范围来实现;由于它们是懒洋洋地运行的,如果它们不使用闭包作用域来保持依赖的嵌套变量处于活动状态,那么当它们运行完时,作用域可能就不存在了^{}理解过去是在没有闭包的情况下执行的,但它会导致一些奇怪的工件(例如,在类定义中运行foo = [x for x in y]会给类一个名为x的类属性,该属性的最终值是x在理解中接受的),在Python3中,所有的理解都被更改为使用隐式闭包范围(这只是listcomps的一个更改dictset理解后来被添加,并且从一开始就使用闭包作用域)

相关问题 更多 >