Учитывая список имен переменных в Python, как мне создать словарь с именами переменных в качестве ключей (к значениям переменных)?

У меня есть список имен переменных, например:

['foo', 'bar', 'baz']

(Изначально я спросил, как преобразовать список переменных. См. Ответ Грега Хьюджилла ниже.)

Как преобразовать это в словарь, где ключи - это имена переменных (в виде строк), а значения - это значения переменных?

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

Моддинг вниз. Я не вижу разумной ситуации, в которой вы бы хотели это сделать, и я не вижу способа сделать это надежным, и уж тем более с eval. Что делать, если имя списка имен скрывает одно из интересующих имен и т. д.

ddaa 23.10.2008 22:55

Ответ на обновление в ответ на мой комментарий: Идиома Python для этого (которую я не поддерживаю, но я видел, как использовалась) - это напрямую "string% locals ()".

ddaa 23.10.2008 23:32

Вы можете заменить dict((x, locals()[...) просто vars().

jfs 11.11.2008 11:15

Пример: a, b = 1, 'astring'; print("%(a)s %(b)s %(b)r" % vars())

jfs 11.11.2008 11:18
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
16
4
23 926
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ваш исходный список [foo, bar, baz] не содержит переменной имена, он просто содержит элементы, которые ссылаются на тот же значения, что и перечисленные вами переменные. Это потому, что у вас может быть два разных имени переменных, которые ссылаются на одно и то же значение.

Таким образом, список сам по себе не содержит информации о том, какие другие имена относятся к объектам. Первый элемент в вашем массиве имеет имя 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.

Вы можете использовать составные части списка или генератора для создания списка кортежей ключей и значений, используемых для непосредственного создания экземпляра 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 () непосредственно в расширение строки, и она выберет желаемые значения.

Если, однако, эти строки могут когда-либо поступать из внешнего источника (например, файлов перевода), тогда рекомендуется фильтровать locals ()

поскольку в dict могут быть неиспользуемые ключи, вы можете просто использовать "..."% locals () без фильтрации

user3850 24.10.2008 00:25

Согласны, "..."% locals () тоже гораздо более питонический, в том смысле, что это обычная идиома.

ephemient 24.10.2008 06:44

Я заставил это работать, используя dict ([(name, locals () [name]) для имени в list_of_variable_names])

pheon 28.12.2015 05:39

Неэффективно, но без вызова 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)

в зависимости от того, что вы хотите.

Ответ принят как подходящий

Забудьте о фильтрации locals()! Словарь, который вы передаете строке форматирования, может содержать неиспользуемые ключи:

>>> name = 'foo'
>>> zip = 123
>>> unused = 'whoops!'
>>> locals()
{'name': 'foo', 'zip': 123, ... 'unused': 'whoops!', ...}
>>> '%(name)s %(zip)i' % locals()
'foo 123'

С новым функция f-string в Python 3.6 использование locals() больше не требуется:

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

и если вы используете метод str.format (), сделайте это так: '{name} {zip}'.format(**locals())

krupan 16.06.2011 18:21

Другие вопросы по теме