for循环中的Sympy解算器错误



所以我玩Sympy是为了构建一个通用的物理问题求解器/生成器。一个组成部分是,我要找一个函数,它将使用kwargs,并根据它得到的结果,重新排列方程并替换其中的值。多亏了SO,我找到了我需要的东西。

但是。。。。。我曾尝试将sympy.solve放入for循环中以生成所有这些表达式,但我遇到了。。。。某物

import sympy
R, U, I, eq = sympy.symbols('R U I eq')
eq = R - U/I
for x in 'RUI':
    print(x)
    print(sympy.solve(eq, x))

输出?

R
[U/I]
U
[I*R]
I
[]

然而,每当我执行sympy.solve(eq, I)时,它就会工作并返回[U/R]

现在,我猜问题在于使用I作为虚单位的sympy,以及隐藏在块中的变量,但即使我在for循环(以及等式)中传递符号声明,我仍然会遇到同样的问题。

我不确定我最终会非常需要这个,但至少可以说这很有趣。

它更像是一个未记录的功能,而不是一个bug。循环for x in 'RUI'等效于for x in ['R', 'U', 'I'],意味着x运行在一个字符字符串上,而不是符号。在循环中插入print(type(x))以查看此内容。注意,sympy.solve(eq, 'I')返回[]

循环for x in [R, U, I]对每个变量进行正确求解。这是编写这个循环的正确方法。

令人惊讶的是,当传递一个字符串作为solve的第二个参数时,你会得到任何东西。Sympy文档没有列出可接受参数中的字符串。显然,它试图将字符串强制为一个sympy对象,但并不总是正确猜测您的意思:与sympy.solve(eq, 'R')一起使用,但与sympy.solve(eq, 'I') 不一起使用

问题是,一些sympy函数"意外"使用字符串作为输入,因为它们在输入时调用sympify。但sympify('I')给出的是虚单位(sqrt(-1)),而不是符号("I")。

你应该总是像一样明确地定义你的符号

R, U, I = symbols("R U I")

并使用这些而不是字符串。

请参阅https://github.com/sympy/sympy/wiki/Idioms-and-Antipatterns#strings-作为输入,了解为什么应避免在SymPy中使用字符串的更多信息。

最新更新