我需要以字符串的形式接受用户输入,将其解析为sympy表达式,然后求解变量。除了log2(x)之外,大多数用户允许的函数都与sympy函数匹配,这相当于sympy的log(x,2)。
我已经尝试过定义python函数的方法,该函数返回所提到的here的sympy函数。我也尝试过使用lambda定义一个sympy函数。在将变量替换为数字之后,这两种方法都可用于获取表达式的值,但如果调用sympy.solve来求解变量,则会创建错误。例如:
import sympy
from sympy.parsing.sympy_parser import parse_expr
def log2(x):
return sympy.log(x, 2)
t, k, y = sympy.symbols('t k y')
parsed = parse_expr("log2(t + k) + k - y")
sympy.solve(parsed, k)
引发NotImplementedError。使用lambda返回类似的结果。如果用log(t + k,2)替换log2(t + k),则上述代码有效。我假设这是因为sympy函数是具有许多不同方法的对象,而sympy.solve尝试调用我的python函数中未实现的方法。我正在寻找一种解决方案,不需要为我的函数创建一个与log的实现长度相同的类。有没有办法让sympy识别并使用log2而不创建一个长类来处理每一个可能的调用?我可以以某种方式创建一个短类定义,将任何方法调用传递给log(x,2)?
答案 0 :(得分:3)
解析器不会自动匹配" log2"在您创建的函数的给定字符串中。你必须用local_dict={"log2": log2}
明确告诉它要做什么。
或者只是将lambda直接放入local_dict:
import sympy
from sympy.parsing.sympy_parser import parse_expr
t, k, y = sympy.symbols('t k y')
parsed = parse_expr("log2(t + k) + k - y", local_dict={"log2": lambda x: sympy.log(x, 2)})
print(sympy.solve(parsed, k))
输出:[(-t*log(2) + LambertW(exp((t + y)*log(2))*log(2)))/log(2)]