我试图用以下方式创建一个包含字典理解的字典(这是一个更大的代码的一部分)
columns = ['zeta', 'Lm', 'u_mean']
print('zeta', eval('zeta'))
print(locals())
dic = {col: [eval(col)] for col in columns}
第一个打印完全按照预期打印(变量zeta的值),第二个打印确认zeta在locals字典中,但在字典中,comprehension命令python失败,出现此错误
NameError: name 'zeta' is not defined
不幸的是,当试图重现错误以便在此发布时,我发现我无法重现错误,因为以下命令在ipython中有效:
zeta,Lm,u_mean=1,4,69
columns=['zeta', 'Lm', 'u_mean']
print('zeta',eval('zeta'))
print(locals())
dic={ col : [eval(col)] for col in columns }
只有我的代码中的那些命令才能工作.
那么,我错过了什么吗?我可以做一些测试来看看有什么问题吗?
解决方法:
字典理解在新范围内执行,很像嵌套函数调用.您不能指望在列表推导中访问父作用域的本地.
我强烈建议你不要使用这样的本地人.创建一个单独的字典作为命名空间,并在其中查找列:
namespace = {
'zeta': value_for_zeta,
# ... etc.
}
然后使用{col:[namespace [col]]作为列中的col}.
如果做不到这一点,你可以将locals()字典存储在一个新变量中并引用它;直接或通过将其作为eval()的命名空间传递:
namespace = locals()
dic = {col: [eval(col, namespace)] for col in columns}
或者干脆:
namespace = locals()
dic = {col: [namespace[col]] for col in columns}
这现在有效,因为命名空间是一个闭包;取自父作用域的名称.
请注意,相同的限制适用于生成器表达式,集合理解以及Python 3中的列表推导. Python 2列表推导在所有其他类型之前实现,并遵循不涉及新范围的不同实现策略,但是这种方法不允许生成器表达式工作,并且通常发现具有单独范围的新方法更好地工作.
标签:python,dictionary,dictionary-comprehension
来源: https://codeday.me/bug/20190528/1168973.html