如何根据Python中的变量名列表创建字典,以变量名为键(对应变量值)?

16 投票
4 回答
28402 浏览
提问于 2025-04-11 09:31

我有一份变量名的列表,像这样:

['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'])

4 个回答

4

你最开始的列表 [foo, bar, baz] 里并不包含变量 names,它只是包含了一些元素,这些元素指向你列出的变量所代表的相同 。这意味着你可以有两个不同的变量名,它们指向的是同一个值。

所以,这个列表本身并不包含关于其他名字如何指向这些对象的信息。你数组里的第一个元素叫 foo,但它也可以叫 a[0](假设你的数组叫 a)。在执行以下代码后,quux 也会指向同一个对象:

quux = a[0]

更新:你说得对,确实可以用 eval() 来实现这个,但一般不推荐使用。Python 提供了一个特殊的成员 __dict__,它包含了当前模块的符号表。所以你可以:

import __main__
d = dict((x, __main__.__dict__[x]) for x in list_of_variable_names)

在你的代码位于没有名字的主模块时,需要 import __main__ 是 Python 的一个小特点。

5

你可以使用列表或生成器推导式来创建一个包含键值对的列表,这样可以直接用来生成一个字典。最好的方法如下:

dict((name, eval(name)) for name in list_of_variable_names)

另外,如果你知道某些变量在本地符号表中存在,你可以直接从 locals 中获取这些变量,这样就不用使用有风险的 eval 了:

dict((name, locals()[name]) for name in list_of_variable_names)

在你最后的更新之后,我觉得下面的答案正是你想要的。如果你只是用这些字符串来进行字符串扩展,并且这些字符串是你自己控制的,那么直接把 locals() 传给字符串扩展就可以了,它会自动挑选出你需要的值。

但是,如果这些字符串可能来自外部来源(比如翻译文件),那么最好对 locals() 进行过滤。

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 特性 让你不再需要使用 locals() 了:

>>> name = 'foo'
>>> zip = 123
>>> unused = 'whoops!'
>>> f'{zip: >5} {name.upper()}'
'  123 FOO'

撰写回答