假设我定义以下表达式:
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()
一样使用factor函数对其进行适当的分解。问题在于,由于组成表达式的元组是不可变的,所以我不能仅用上面计算的表达式替换poly1
的一部分。有没有比从头开始重建整个表达式更好的替代因式多项式的方法?
注意:我不希望使用subs()
方法,因为它会搜索整个表达式,并且似乎在某些情况下,您可能希望对修改的不同部分非常具体。 / p>
答案 0 :(得分:1)
常量的自动分布是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
的 this 实例是应替换的实例。