我有一个变量名列表,如下所示:
['foo', 'bar', 'baz']
(我最初问过如何转换变量列表。请参阅Greg Hewgill的答案。)
如何将其转换为字符串,其中键是变量名称(作为字符串),值是变量的值?
{'foo': foo, 'bar': bar, 'baz': baz}
现在我再问这个问题,我想出了:
d = {}
for name in list_of_variable_names:
d[name] = eval(name)
可以改进吗?
更新,回答我想要这样做的问题(在评论中):
我经常发现自己使用%运算符来为字符串添加要插入的名称和值的字典。通常,字符串中的名称只是局部变量的名称。所以(下面的答案)我可以做这样的事情:
message = '''Name: %(name)s
ZIP: %(zip)s
Dear %(name)s,
...''' % dict((x, locals()[x]) for x in ['name', 'zip'])
答案 0 :(得分:16)
忘记过滤locals()
!您为格式化字符串提供的字典允许包含未使用的密钥:
>>> name = 'foo'
>>> zip = 123
>>> unused = 'whoops!'
>>> locals()
{'name': 'foo', 'zip': 123, ... 'unused': 'whoops!', ...}
>>> '%(name)s %(zip)i' % locals()
'foo 123'
使用Python 3.6中的新f-string feature,不再需要使用locals()
:
>>> name = 'foo'
>>> zip = 123
>>> unused = 'whoops!'
>>> f'{zip: >5} {name.upper()}'
' 123 FOO'
答案 1 :(得分:4)
您的原始列表[foo, bar, baz]
不包含变量 names ,它只包含与您列出的变量引用相同值的元素。这是因为您可以使用两个不同的变量名来引用相同的值。
因此,列表本身不包含有关其他名称引用对象的信息。数组中的第一个元素的名称为foo
,但它的名称为a[0]
(假设您的数组名为a
)。执行以下代码后,quux
也引用相同的对象:
quux = a[0]
更新:您可以使用eval()
,但通常不鼓励使用import __main__
d = dict((x, __main__.__dict__[x]) for x in list_of_variable_names)
。 Python提供了一个名为__dict__
的特殊成员,它包含当前模块的符号表。所以你可以:
import __main__
当你的代码在未命名的主模块中时,{{1}}是一个Python的怪癖。
答案 2 :(得分:4)
您可以使用list或generator comprehensions来构建用于直接实例化dict的键值元组列表。最好的方法如下:
dict((name, eval(name)) for name in list_of_variable_names)
此外,如果您知道,例如,变量存在于本地符号表中,您可以通过直接从本地变量查看变量来避免危险的eval:
dict((name, locals()[name]) for name in list_of_variable_names)
在您最后更新之后,我认为以下答案确实是您想要的。如果您只是使用它来控制字符串扩展,只需将locals()直接传递给字符串扩展,它就会挑选出所需的值
但是,如果这些字符串可能来自外部来源(例如翻译文件),那么过滤本地人()
是个好主意。答案 3 :(得分:1)
效率不高,但没有调用eval
:
dict((k,v) for (k,v) in globals().iteritems() if k in list_of_variable_names)
或
dict((k,v) for (k,v) in vars().iteritems() if k in list_of_variable_names)
取决于你想要的东西。