Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: Pass inequality as string in dict for evaluation

I need to pass inequalities to a function for evaluation within the function. Is there a way to evaluation the inequality if passed as a string? Or must I pass a representation of the inequality and use if/else statements to generate the sign?

like image 496
Jason Strimpel Avatar asked Feb 23 '23 09:02

Jason Strimpel


2 Answers

Your question is a little vague, but it sounds like you want to evaluate a string containing an expression (such as x > 5). Rather than doing that, which is unnecessarily complex, and potentially a security hazard, just define a function, either in the conventional way or using lambda.

def gt5(x):
    return x > 5

or

gt5 = lambda x: x > 5

These are both equivalent; now you can pass around gt5 however you like, and when the time comes, you simply call it

y = 6
if gt5(y):
    ...

As Gerrat's answer suggests, the operator module may also be useful for things like this.


Now that I know you are processing user strings, I would definitely suggest creating a dictionary that maps strings to functions. (Perhaps that's what you meant in your title?) Passing userland strings into getattr seems bad in a number of ways. What happens if you want to add a string that doesn't correspond to an attribute of operator? What happens if the user passes in a string corresponding to a private attribute? Better to create a custom dictionary mapping strings to functions. A dict allows you to specify just those strings you want to accept.

func_dict = {
    'lt'   : operator.lt,
    'gt'   : operator.gt,
    'nand' : lambda x, y: not (x and y)
}

You could still save yourself work by using getattr + operator to build the dict from a list of strings that you want to accept. Something like:

func_dict = dict((s, getattr(operator, s)) for s in ['lt', 'gt'])

Then update func_dict like so:

custom_dict = {
    'nand' : lambda x, y: not (x and y)
}

func_dict.update(custom_dict)

From there you can easily call functions in the dict like so:

>>> func_dict['lt'](5, 7)
True
like image 188
senderle Avatar answered Feb 26 '23 00:02

senderle


You could use the operator module, and pass the appropriate method on it:

import operator

def check(op, a, b)
    return op(a,b)

op = operator.ne
check(op, 2,3)


>>> True
like image 43
Gerrat Avatar answered Feb 26 '23 00:02

Gerrat