Узнайте о доступных переменных в форматировании именованных строк Python

Учитывая строку шаблона/форматирования "{foo}_{bar}", как я могу программно извлечь необходимые ключи форматирования ["foo", "bar"]?

У меня есть параметры для различных экспериментов

[
    {"parameters": {"foo": 1, "bar": 2}, "format": `"{foo}_{bar}"`},
    {"parameters": {"biz": 3}, "format": "{biz}_{baz}"}
]

Как видите, во втором наборе параметров отсутствует ключ baz. Поэтому, когда я делаю что-то вроде

"{biz}_{baz}".format(**parameters), вызывает KeyError, потому что baz отсутствует.

Я хочу заменить все отсутствующие параметры на NR и заполнить все доступные параметры их значениями.

Результат тогда:

[
    {"parameters": {"foo": 1, "bar": 2}, "format": `"{foo}_{bar}"`, "formatted": "1_2"},
    {"parameters": {"biz": 3}, "format": "{biz}_{baz}", "formatted": "3_NR"}
]

Для контекста: у меня есть более 100 строк, и нет согласованности между ожидаемыми параметрами, необходимыми для этой строки.

@jonrsharpe Мне кажется, что это не точная копия, поскольку его намерения немного отличаются или сложны. Хотя название немного неудачное.

Bram Vanroy 13.12.2020 22:54

@BramVanroy дубликат точно отвечает на выделенное жирным шрифтом первое предложение

jonrsharpe 13.12.2020 22:55

@jonrsharpe Точно, но если вы прочитаете дальше, у этого пользователя на самом деле есть очень конкретная конечная цель. Я считаю, что это то, вокруг чего вращается этот вопрос, поскольку это та часть, которая на самом деле поможет им намного больше, чем просто этот первый вопрос. Я уверен, что если OP приложит некоторые усилия, чтобы переписать пост, чтобы подчеркнуть конечную цель, его можно будет открыть повторно.

Bram Vanroy 13.12.2020 23:00

@BramVanroy, может быть, но голосование за открытие до того, как они это сделают, кажется преждевременным, и, возможно, они спросили о том, на чем они на самом деле застряли.

jonrsharpe 13.12.2020 23:05

Привет, ребята, выделенное жирным шрифтом предложение - это все, с чем мне действительно нужна помощь. Кажется, что правильный ответ на этот вопрос на самом деле является принятым ответом в связанном посте. stackoverflow.com/questions/22830226/…. Прежде чем задать вопрос, я провел поиск по переполнению стека, но почему-то пропустил этот пост. Спасибо вам обоим за помощь!

Parmandeep Chaddha 13.12.2020 23:14

@BramVanroy, так что теперь он снова открыт, несмотря на то, что ответ обманщика решает проблему ОП; это неоптимальный результат, потому что следующий человек, который найдет это, увидит хрупкое решение ниже, если он не войдет в комментарии или не прочитает связанные вопросы. Было бы хорошо подождать, пока ОП уточнит через редактирование, нужно ли повторно открывать вопрос.

jonrsharpe 14.12.2020 10:42

@jonrsharpe Ты прав. Я должен был подождать с повторным голосованием, пока OP не изменит свой пост, что в конце концов они сочли ненужным. Не уверен, что все еще можно проголосовать за закрытие. Извини, моя ошибка.

Bram Vanroy 14.12.2020 13:06
Почему в 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 может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
7
123
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Вы можете эффективно собрать необходимые имена параметров из строки, а затем проверить, есть ли какие-либо отсутствующие ключи, проверив сходство наборов между фактическими ключами. Если отсутствуют ключи, добавьте их со значением «NR». Наконец, используйте .format, чтобы правильно отформатировать строку в «форматированный» ключ.

ds = [
    {"parameters": {"foo": 1, "bar": 2}, "format": "{foo}_{bar}"},
    {"parameters": {"biz": 3}, "format": "{biz}_{baz}"}
]

for d in ds:
    # Copy params so that we do not change params in-place
    params = d["parameters"]
    req_keys = set(d["format"][1:-1].split("}_{"))
    missing_keys = req_keys.difference(params.keys())

    if len(missing_keys) > 0:
        params = {**params, **{key: "NR" for key in missing_keys}}

    d["formatted"] = d["format"].format(**params)

print(ds)

# [{'parameters': {'foo': 1, 'bar': 2}, 'format': '{foo}_{bar}', 'formatted': '1_2'}, {'parameters': {'biz': 3}, 'format': '{biz}_{baz}', 'formatted': '3_NR'}]

Сделал почти так же, только заменил req_keys = set(d["format"][1:-1].split("}_{")) на req_keys=[var for _, var, _, _ in Formatter().parse(d['format']) if var]. Это позволяет избежать привязки всего к "}_{" на случай, если в будущем произойдут изменения.

Parmandeep Chaddha 13.12.2020 23:18

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