字典中的Eval函数使用单个引用但不作为字典理解
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了字典中的Eval函数使用单个引用但不作为字典理解相关的知识,希望对你有一定的参考价值。
我有一个变量和值列表,我使用eval语句分配给它们。
我试图使用字典理解来匹配变量与评估值。
当我在范围(0,10)中使用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'没有定义。有没有办法使用字典理解来做到这一点,或者有一个替代,我必须用来解决这个问题。
提前致谢。
你的问题是由于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
(因为迭代的第一个可迭代作为参数传递给虚函数,而不是通过闭包范围)。
问题是,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
理解只是让它完全打破。
这样做的原因是,理解的语言定义是基于生成器表达式的定义构建的,而生成器表达式必须用闭包范围来实现;因为它们懒惰地运行,如果它们没有使用闭包范围来保持它们依赖于活动的嵌套变量,那么当它们用完时,范围可能不再存在。 Python 2中的list
理解用于在没有闭包的情况下执行,但它引起了一些奇怪的工件(例如,在类定义中运行foo = [x for x in y]
会给类一个名为x
的类属性,其中最终值为x
,并且在Python 3中),所有的理解都改为使用隐式闭包范围(这只是listcomps的一个变化;后来添加了dict
和set
的理解,并从一开始就使用了闭包范围)。
以上是关于字典中的Eval函数使用单个引用但不作为字典理解的主要内容,如果未能解决你的问题,请参考以下文章