Как подставить значение переменных в выражение Python, но не вычислять выражение?

У меня есть выражение Python, которое выглядит следующим образом:

var1 = 'GOOGLE'
var2 = '5'
expr = 'df[df[var1]>=var2]'

В моей рабочей области var1 и var2 определены правильно, поэтому я могу оценить expr следующим образом:

eval(expr)

Однако я хочу передать это выражение (в виде строки) другой функции с заменой в ней значений var1 и var2. Я не хочу передавать переменные var1 и var2, так как у меня может быть любое количество переменных, а не только две. Как мне это сделать?

en.wikipedia.org/wiki/XY_problem
flakes 22.11.2022 07:58

Я бы использовал словарь или пользовательский объект, чтобы собрать все переменные, которые вы хотите передать своей функции, в один входной аргумент. Подойдет ли это для вашей проблемы?

PieCot 22.11.2022 08:01

Какой у Вас вопрос? Пока ваш вопрос не ясен. Вы хотите знать, как создать функцию, которая принимает различные (любое количество) аргументы или что?

Maxwell D. Dorliea 22.11.2022 08:03

@PieCot Да, это возможное решение, но я хочу, чтобы переменные были заменены, чтобы человеку, выполняющему задачу ниже по течению, не нужно было беспокоиться о замене переменных.

Zing 22.11.2022 08:04

@MaxwellD.Dorliea: я просто хочу преобразовать строку df[df[var1]>=var2] в df[df['GOOG']>=5] без ее оценки.

Zing 22.11.2022 08:06

@Zing Просто используйте f-строку

Maxwell D. Dorliea 22.11.2022 08:07

Еще одно очень глупое решение — использование replace, но, на мой взгляд, очень опасное: expr.replace('var1', f"'{var1}'").replace('var2', var2). Я бы не стал его использовать. Ясно, что вы можете автоматизировать, перебирая все переменные, которые хотите заменить.

PieCot 22.11.2022 08:09

@flakes: Спасибо, что потратили время, чтобы сообщить мне, что это проблема XY.

Zing 22.11.2022 08:12

@Zing Я ответил на твой вопрос?

Maxwell D. Dorliea 22.11.2022 08:13

@MaxwellD.Dorliea: Это похоже на решение, но мне потребуется добавить фигурные скобки в выражение, прежде чем я его использую. Спасибо.

Zing 22.11.2022 08:14

@Zing не забудь отметить как правильный✅ если я отвечу на твой вопрос

Maxwell D. Dorliea 22.11.2022 08:16
Почему в 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
11
88
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы можете просто использовать f-строку Python, как показано ниже.

expr = f'df[df[{var1}] >= {var2}]'

Это возможное решение, но мне потребуется добавить фигурные скобки вокруг переменных, которых я хотел избежать.

Zing 22.11.2022 08:15
Ответ принят как подходящий

Вы можете проанализировать выражение с помощью ast.parse и использовать подкласс ast.NodeTransformer для преобразования узлов Name в соответствующие значения в виде узлов Constant, а затем преобразовать AST обратно в код с помощью ast.unparse:

import ast

var1 = 'GOOGLE'
var2 = '5'
expr = 'df[df[var1]>=var2]'

class NamesToConstants(ast.NodeTransformer):
    def visit_Name(self, node):
        if node.id in globals(): # feel free to use your own dict instead of globals()
            value = globals()[node.id]
            try: # convert value to integer if viable
                value = int(value)
            except:
                pass
            return ast.Constant(value=value)
        return node

tree = ast.parse(expr)
NamesToConstants().visit(tree)
print(ast.unparse(tree))

Это выводит:

df[df['GOOGLE'] >= 5]

ast.unparse требуется Python 3.10 или новее. Если вы используете более раннюю версию, вместо этого вы можете использовать astunparse.unparse из пакета astunparse.

Демо: https://trinket.io/python3/18cc1182d0

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