【问题标题】:Turn string into operator将字符串变成运算符
【发布时间】:2010-12-16 23:28:30
【问题描述】:

如何将"+"之类的字符串变成运算符加号?

【问题讨论】:

标签: python evaluation


【解决方案1】:

使用查找表:

import operator
ops = { "+": operator.add, "-": operator.sub } # etc.

print(ops["+"](1,1)) # prints 2 

【讨论】:

    【解决方案2】:
    import operator
    
    ops = {
        '+' : operator.add,
        '-' : operator.sub,
        '*' : operator.mul,
        '/' : operator.truediv,  # use operator.div for Python 2
        '%' : operator.mod,
        '^' : operator.xor,
    }
    
    def eval_binary_expr(op1, oper, op2):
        op1, op2 = int(op1), int(op2)
        return ops[oper](op1, op2)
    
    print(eval_binary_expr(*("1 + 3".split())))
    print(eval_binary_expr(*("1 * 3".split())))
    print(eval_binary_expr(*("1 % 3".split())))
    print(eval_binary_expr(*("1 ^ 3".split())))
    

    【讨论】:

    • 在 python3 中,这给出:'+' : operator.add, AttributeError: 'str' object has no attribute 'add'
    • 问题是命名不佳的operator 参数与导入的运算符模块发生冲突。我猜你内联了get_operator_fn 和eval_binary_expr。将operator 参数更改为其他参数,例如oper,以及对它的所有引用。查看我的编辑。
    • 对于 Python3,您还必须将 operator.div 更改为 operator.truediv,并修复所有打印语句。
    • 注意:这会在每次调用时从头开始重建查找 dict,从而消除了 O(1) 查找优势。在函数外部定义dict,使其只构建一次。
    • 更彻底,@PaulMcG,Python3 为 operator.truediv(返回浮点数)和 operator.floordiv(Python2 风格的整数除法)删除了 operator.div
    【解决方案3】:

    您可以尝试使用 eval(),但如果字符串不是来自您,则很危险。 否则你可能会考虑创建一个字典:

    ops = {"+": (lambda x,y: x+y), "-": (lambda x,y: x-y)}

    等...然后调用

    ops['+'] (1,2)
    或者,用于用户输入:
    if ops.haskey(userop):
        val = ops[userop](userx,usery)
    else:
        pass #something about wrong operator

    【讨论】:

      【解决方案4】:

      如何使用查找字典,但使用 lambdas 而不是运算符库。

      op = {'+': lambda x, y: x + y,
            '-': lambda x, y: x - y}
      

      那么你可以这样做:

      print(op['+'](1,2))
      

      它会输出:

      3
      

      【讨论】:

        【解决方案5】:

        每个算子都有对应的魔法方法

        OPERATORS = {'+': 'add', '-': 'sub', '*': 'mul', '/': 'div'}
        
        def apply_operator(a, op, b):
        
            method = '__%s__' % OPERATORS[op]
            return getattr(b, method)(a)
        
        apply_operator(1, '+', 2)
        

        【讨论】:

        • 这个很好用,谢谢分享。为了验证,我们可以扩展 apply_operator。 if op == '/' and b == 0: return np.inf if op == '/' and a == 0: return 0
        • 这不会让NotImplemented 正常工作。
        【解决方案6】:

        如果安全则使用eval()(不在服务器等):

        num_1 = 5
        
        num_2 = 10
        
        op = ['+', '-', '*']
        
        result = eval(f'{num_1} {op[0]} {num_2}')
        
        print(result)
        

        输出: 15

        【讨论】:

        • 不鼓励使用eval 存在安全风险。
        【解决方案7】:

        我了解您想要执行以下操作: 5"+"7 其中所有 3 件事都将通过变量传递, 所以 示例:

        import operator
        
        #define operators you wanna use
        allowed_operators={
            "+": operator.add,
            "-": operator.sub,
            "*": operator.mul,
            "/": operator.truediv}
        
        #sample variables
        a=5
        b=7
        string_operator="+"
        
        #sample calculation => a+b
        result=allowed_operators[string_operator](a,b)
        print(result)
        

        【讨论】:

          【解决方案8】:

          我遇到了同样的问题,使用 Jupyter Notebook 时,我无法导入操作员模块。所以上面的代码帮助我了解了但无法在平台上运行。我想出了一个有点原始的方法来使用所有基本功能,它是:(这可能会被大量改进,但它是一个开始......)

          # Define Calculator and fill with input variables
          # This example "will not" run if aplha character is use for num1/num2 
          def calculate_me():
              num1 = input("1st number: ")
              oper = input("* OR / OR + OR - : ")
              num2 = input("2nd number: ")
          
              add2 = int(num1) + int(num2)
              mult2 = int(num1) * int(num2)
              divd2 = int(num1) / int(num2)
              sub2 = int(num1) - int(num2)
          
          # Comparare operator strings 
          # If input is correct, evaluate operand variables based on operator
              if num1.isdigit() and num2.isdigit():
                  if oper is not "*" or "/" or "+" or "-":
                      print("No strings or ints for the operator")
                  else:
                      pass
                  if oper is "*":
                      print(mult2)
                  elif oper is "/":
                      print(divd2)
                  elif oper is "+":
                      print(add2)
                  elif oper is "-":
                      print(sub2)
                  else:
                      return print("Try again")
          
          # Call the function
          calculate_me()
          print()
          calculate_me()
          print()
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-03-24
            • 1970-01-01
            • 2018-06-18
            相关资源
            最近更新 更多