假设我定义以下表达式:
poly1 = 6/(25*(x + 3)) + 1/(5*(x + 3)**2)
打印出:
6/(25*x + 75) + 1/(5*(x + 3)**2)
关于这个表达我有两个问题。首先,有没有办法使表达式保持我输入的格式?特别是,我可以做些什么来将第一项的分母保留为 25*(x + 3)
?
其次,如果我有打印形式的表达式,那么分解表达式、重新格式化第一项的分母,然后将其重新组合在一起的最佳方法是什么?理想情况下,我可以使用一系列 args 调用来深入研究表达式,以获得第一项的分母,然后使用因子函数对其进行正确分解,如 poly1.args[0].args[1].args[0].factor()
。问题是,由于组成表达式的元组是不可变的,我不能只用上面计算的表达式替换一段 poly1
。有没有比从头开始重建整个表达式更好的方法来替换因式多项式?
注意:我不想使用 subs()
方法,因为它会搜索整个表达式,而且似乎在某些情况下您可能希望非常具体地了解不同的表达式您修改的部分。
最佳答案
常量的自动分配是touchy subject 。有一个选项可以禁用它,如下所示:
from sympy.core.evaluate import distribute
with distribute(False):
poly1 = 6/(25*(x+3)) + 1/(5*(x + 3)**2)
print(poly1) # 6/(25*(x + 3)) + 1/(5*(x + 3)**2)
或者您可以将 25 包装在 UnevaluatedExpr
中以防止其与其他术语交互。
poly1 = 6/(UnevaluatedExpr(25)*(x+3)) + 1/(5*(x + 3)**2)
print(poly1) # 6*25**(-1)/(x + 3) + 1/(5*(x + 3)**2)
或者在分母中使用未计算的乘积 (Mul):
poly1 = 6/Mul(25, x+3, evaluate=False) + 1/(5*(x + 3)**2)
print(poly1) # 6/(25*(x + 3)) + 1/(5*(x + 3)**2)
或者将分母包装在 factor_terms
中——一种更温和的 factor
形式,它可以提取系数,而不会对表达式造成太多困惑。
poly1 = 6/factor_terms(25*(x+3)) + 1/(5*(x + 3)**2)
print(poly1) # 6/(25*(x + 3)) + 1/(5*(x + 3)**2)
或者通过引入看起来像数字的符号来作弊:
c25 = symbols('25')
poly1 = 6/(c25*(x+3)) + 1/(5*(x + 3)**2)
print(poly1) # 1/(5*(x + 3)**2) + 6/(25*(x + 3))
建议阅读:Prevent expression evaluation
第二个问题,关于有针对性的替代,很难笼统地回答。必须recurse through the expression tree ,将 expr
重建为 expr.func(*args)
,其中 args
是 expr.args
,可能已修改。主要问题是您如何知道 25*x + 75
的这个实例是应该被替换的实例。
关于python - 重新格式化 SymPy 中的表达式片段以防止常数系数的分布,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53243409/