Python:使用vars()字典时的问题

时间:2015-06-24 07:13:46

标签: python dictionary

我有以下代码段:

a, b = 1, 2
params = ['a', 'b']
res = {p: vars()[p] for p in params}

这给了我KeyError: 'a',而下面的代码工作正常:

a, b = 1, 2
params = ['a', 'b']
res = {}
for p in params:
    res[p] = vars()[p] 

这有什么区别?

4 个答案:

答案 0 :(得分:9)

没有任何参数的

vars()就像locals()一样,因为字典理解有自己的范围,所以没有名为ab的变量。

您可以在此处使用eval()。没有任何参数,它将以LEGB方式执行,或明确指定globals() dict eval

>>> res = {p: eval(p) for p in params}
>>> res
{'a': 1, 'b': 2}

但是,如果你想使用他们的名字访问变量,那么正确的方法是从头开始创建一个字典。

答案 1 :(得分:5)

因为代码vars中的内容会返回一个字典,其中包含基于文档的 local 变量。

  

如果没有参数,vars()就像locals()一样。

请参阅以下示例:

>>> def a():
...   print vars()
... 
>>> a()
{}

正如您所看到的,我们在函数a中没有任何局部变量,因此vars返回一个空字典。

在您的情况下,作为一种更加pythonic的方式,您可以创建对象的字典:

d={'a':1,'b': 2,'params' : ['a', 'b']}
example_list : ['a', 'b']
res = {p: d[p] for p in example_list}

答案 2 :(得分:3)

似乎Python在字典理解中创建了一个闭包(例如,dictcomp

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in <dictcomp>
KeyError: 'a'

答案 3 :(得分:3)

在for循环中使用vars()作为您给出的第二个代码。

# come out with {'a': 1, 'b': 2}
res = {p: v for p, v in vars().iteritems() if p in params}
res = {'a': vars()['a'], 'b': vars()['b']}

我们可以在dict理解中找出locals/vars循环中的新for

>>> {i: list(vars().viewkeys()) if i == 0 else list(vars().viewvalues()) for i in range(2)}
{0: ['i', '.0'], 1: [1, <listiterator at 0x6fffe458550>]}
>>> {list(vars().viewkeys())[i]: list(vars().viewvalues())[i] for i in range(2)}
{'.0': <listiterator at 0x6fffe458710>, 'i': 0}