Search code examples
pythonfunctionsigninequality

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?


Solution

  • 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