Skip to main content
 首页 » 编程设计

python之Sympy 的订阅限制

2025年05月04日15jillzhang

我正在处理一些长方程但并不复杂,我想使用 sympy 来简化和“分解”它们。但是我遇到了一些问题。以下是一些最小示例的列表:

问题一:对称性

from sympy import * 
from __future__ import division 
a = symbols('a') 
b = symbols('b') 
expr = 1/12*b + 1 
expr.subs(1/12*b, a) 
expr.subs(b*1/12, a) 

第一行给出预期结果(即。a+1),而第二行没有替换。

问题 2:因式分解

表达式的某些部分被分解,当我展开表达式时,它们会得到简化,因此无法进行替换。例如

(((x+1)**2-x).expand()).subs(x**2+2*x, y+1) 

将给出 x^2+x+1 而我正在寻找的是 y+2-x。

问题

有没有办法解决这些问题?或者也许我应该使用另一种符号数学工具?欢迎提出任何建议。

请您参考如下方法:

在 SymPy 中有一个主要问题,那就是,由于 Python 的工作方式,number/number 给出一个 float (或者如果您使用 Python 2 而不是进行整数除法来自 __future__ 导入部门)。

在第一种情况下,在您的原始表达式中,Python 从左到右计算 1/12*b。 1/12 由 Python 计算得到 0.08333333333333333,然后乘以 b。在第二种情况下,b*1 被评估为 b。然后 b/12 被 SymPy 求值(因为 b 是一个 SymPy 对象),得到 Rational(1, 12)*b。

由于 float 的不精确性,SymPy 不会将 float 0.08333333333333333 视为等于有理数 1/12。

这个问题还有一些讨论here .作为解决方法,您应该避免直接 integer/integer 而不以某种方式包装它,以便 SymPy 可以创建有理数。以下都将创建一个有理数:

b/12 
Rational(1, 12)*b 
S(1)/12*b 

对于 (((x+1)**2-x).expand()).subs(x**2+2*x, y+1) 问题是 x**2 + 2*x 没有准确出现在表达式中,即 x**2 + x + 1。 SymPy 通常只替换它准确看到的东西。

看来您不介意添加和减去 x 来使替换工作正常进行。所以我建议改为 (((x+1)**2-x).expand()).subs(x**2, y+1 - 2*x)。通过仅替换单个项 (x**2),替换将始终有效,并且 2*x 将取消以留下任何 x 术语保留(在本例中为 -x)。