【问题标题】:String in list, into a function列表中的字符串,放入函数
【发布时间】:2017-03-29 18:40:45
【问题描述】:
myList = ['100', 'sin(x)', '0', '1']

我从一个文本文件中读取这些字符串。我现在想从该字符串执行函数调用 sin(x) -- 我希望这是对任何函数表达式的字符串的一般解释。

我尝试了以下但没有成功。

myList[1].replace("'", "")

我想我要问的是如何从列表中提取字符串并使用它的“原始文本”。

最终目标是得到这个函数,这里myList[1]应该转向sin(x)

from math import sin
def f(x):
    return myList[1]

因此 f(x) 将从此列表中给出 sin(x) 的计算值。

【问题讨论】:

  • eval,但请确保您确实需要解决这个问题。 eval 被滥用会很危险。这让我觉得是一个 XY 问题。
  • 您对我的回答的评论更适合这里。这仍然是一个狭窄的范围。您是否正在尝试编写某种表达式评估器?整体项目是什么?
  • @Prune:在他之前的帖子中,有一个带有任务列表“N function_string a b”的文本文件,目标是在[a,b]区间内对每个任务进行数值积分,并在@中细分987654329@ 子间隔。
  • 谢谢;在 SO 中,每个问题都应该独立存在,或者至少包含指向 SO 上下文的链接。
  • 另请参阅stackoverflow.com/a/5936822/3088138stackoverflow.com/a/25437733/3088138 以及围绕这些的其他答案。

标签: python list python-3.x math


【解决方案1】:

使用 dict 并将其存档

from math import sin
myList = ['100', 'sin(x)', '0', '1']
options = { 'sin(x)':sin }
options[myList[1]](1)
0.8414709848078965

【讨论】:

    【解决方案2】:

    您将字符串值与可执行代码混淆了。两个基本点:

    1. 可以使用 eval 函数执行此操作,该函数将字符串评估为 Python 代码。
    2. 不要。真的; eval 是一把上膛的枪,指着你的脚,通常表示系统设计不佳。

    您总体上想要做什么?如果你想通过文本输入触发三角函数,你最好通过枚举检查来完成,例如:

    choice = myList[1]
    if choice == "sin":
        return sin(x)
    elif choice == "cos":
        return cos(x)
    ...
    

    【讨论】:

    • 我试图让 f(x) 返回 myList[1] 中给出的函数。不仅是三角函数,还可以是 log(x), x**2, ....
    【解决方案3】:

    我认为最安全的方法是将预期的函数存储在这样的字典中:

    math_dict = {'sin(x)':sin, 'cos(x)':cos}
    

    那么你可以像这样从列表中调用 sin:

    def f(x):
        return math_dict[myList[1]](x)
    

    我刚刚添加了 cos(x) 以表明您可以使用任意函数来执行此操作。然后你可以做这样的事情来概括它:

    def f(x):
        return math_dict[x] if x in math_dict else None
    

    【讨论】:

      【解决方案4】:

      Sin 函数是数学库的一部分,你可以像这样得到它:

      import math
      getattr(math, 'sin')
      

      这对于所有非内置库都是一样的。只需拆分字符串以获取函数名称:

      function_name = myList[1].split('(')[0]
      function = getattr(math, function_name)
      function(value for x)
      

      对于像round这样的内置函数:

      getattr(globals()['__builtins__'], 'round')
      

      【讨论】:

        【解决方案5】:

        使用sympy.sympify 并突出显示警告

        警告sympify 使用 eval。不要在未经处理的输入上使用它。

        你可以解决这个问题

        myList = ['100', 'sin(x)', '0', '1']
        
        from sympy.abc import x
        from sympy import sympify
        
        N, expr, a,b = myList
        
        # convert strings to objects
        N=int(N); a=float(a); b=float(b);
        expr = sympify(expr)
        
        # define user function
        def f(xval): return expr.subs(x,xval)
        

        或者对于多点评估,将最后一行替换为

        from sympy import lambdify
        f = lambdify(x, expr, "numpy")
        
        # integrate as left Riemann sum (order 1)
        from numpy import linspace
        xlist = linspace(a,b,N)
        
        integral = sum(f(xlist))*(b-a)/N
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-10-15
          • 1970-01-01
          • 2019-02-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-07-13
          相关资源
          最近更新 更多