How to substitute value of variables in Python expression, but not evaluate the expression?
Question:
I have a Python expression that looks like the following:
var1 = 'GOOGLE'
var2 = '5'
expr = 'df[df[var1]>=var2]'
In my workspace var1 and var2 are well defined so I can evaluate expr as follows:
eval(expr)
However, I want to pass this expr (as string) to another function with values of var1 and var2 substituted in it. I do not want to pass the variables var1 and var2, as I can have any number of variables, not just two. How do I accomplish this?
Answers:
You can simply use Python f-string as demonstrated below
expr = f'df[df[{var1}] >= {var2}]'
You can parse the expression with ast.parse
and use a subclass of ast.NodeTransformer
to convert Name
nodes to the corresponding values as Constant
nodes, and then convert the AST back to code with 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))
This outputs:
df[df['GOOGLE'] >= 5]
ast.unparse
requires Python 3.10 or later. If you’re using an earlier version, you can use astunparse.unparse
from the astunparse package instead.
I have a Python expression that looks like the following:
var1 = 'GOOGLE'
var2 = '5'
expr = 'df[df[var1]>=var2]'
In my workspace var1 and var2 are well defined so I can evaluate expr as follows:
eval(expr)
However, I want to pass this expr (as string) to another function with values of var1 and var2 substituted in it. I do not want to pass the variables var1 and var2, as I can have any number of variables, not just two. How do I accomplish this?
You can simply use Python f-string as demonstrated below
expr = f'df[df[{var1}] >= {var2}]'
You can parse the expression with ast.parse
and use a subclass of ast.NodeTransformer
to convert Name
nodes to the corresponding values as Constant
nodes, and then convert the AST back to code with 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))
This outputs:
df[df['GOOGLE'] >= 5]
ast.unparse
requires Python 3.10 or later. If you’re using an earlier version, you can use astunparse.unparse
from the astunparse package instead.