首页 > 解决方案 > 同情错误?即使使用 `evaluate=False` 方程也会自动处理

问题描述

考虑以下 sympy 代码:

from sympy import Add
from sympy.abc import x

t1 = 2+2*x
t2 = x
myeq = sp.UnevaluatedExpr(Add(sp.UnevaluatedExpr(t1), sp.UnevaluatedExpr(t2), evaluate=False))

# BUG! Will print: x + 2*x + 2
# Yet it should print: 2+2*x+x
print(myeq)

此代码片段改编自此答案。那里的条款更简单,所以Add保留了顺序。Add但是在这种情况下,我怎样才能保留订单呢?

(备注:如果我们将条款更改为t1=xt2=x**2我使用sp.UnevaluatedExpr作品的方法,但没有这些条款的原始答案没有。唉,对于我的具体情况,甚至不使用sp.UnevaluatedExpr作品。)

标签: pythonpython-3.xsympyevaluation

解决方案


这不是错误...

...但更多的是缺少的功能。所有这些都被记录在案。

这就是 SymPy 所指的unevaluate

评估意味着它内部的值不会与它外部的表达式交互以提供简化的输出。

在您的示例中,术语2*xx没有像预期的那样简化。

输入顺序

您看到的是 SymPy 没有保留您输入术语的顺序。这记录在表达式树部分下

交换操作的参数AddMul以任意(但一致!)顺序存储,该顺序与输入顺序无关。

这应该不是问题,因为Add并且Mul是可交换的。

虽然,如果由于某种原因,由于乘法的不可交换性,您想保留输入的顺序,您可以这样做。

在 SymPy 中,您可以使用 来创建非交换符号Symbol('A', commutative=False),并且非交换符号的乘法顺序与输入保持相同)

至于现在,似乎没有非交换加法。


推荐阅读